<?php
/**
 * 公共辅助函数
 *
 * @package		Hooloo framework
 * @author 		Bill
 * @copyright 	Hooloo Co.,Ltd
 * @version		1.0
 * @release		2017.05.08
 */
if ( ! defined('BASEPATH')) exit('No direct script access allowed');


/*if (PHP_SAPI != 'cli') {
	$defurl = $_SERVER['SERVER_NAME'];
	$dfu = explode('127.0.0.1', $defurl);

	if (count($dfu) <= 1) {
		$dfu = explode('loanwang.com', $defurl);
	}

	if (count($dfu) <= 1) {
		$dfu = explode('lvmaque.net', $defurl);
	}

	if (count($dfu) <= 1) {
		$dfu = explode('localhost', $defurl);
	}

	if (count($dfu) <= 1) {
		header('Content-type:text/html;charset=\'utf-8\'');
		exit('<div style=\'height:200px;line_height:200px;font-size:24px;text-align:center;\'>对不起,该程序没有对您正在使用的域名进行授权,如需使用，请到联系客服获取授权！</div>');
	}
}*/

if (!function_exists('build_rid_no')) {
    function build_rid_no()
    {
        $numbers = mt_rand(100, 1000) + time();
        return $numbers;
    }
}

if (!function_exists('gs')) {
    function gs($fun, $p = '')
    {
        return plugin_action('GreenSparrow/Sparrow/' . $fun, $p);
    }
}

if (!function_exists('month_config')) {
    function month_config()
    {
        $config['month_loss'] = explode('|', config('month_loss'));
        $config['month_rate'] = config('month_rate');
        $config['month_use_time'] = explode('|', config('month_use_time'));
        $config['month_position'] = config('month_position');
        return $config;
    }
}

if (!function_exists('week_config')) {
    function week_config()
    {
        $config['week_loss'] = explode('|', config('week_loss'));
        $config['week_rate'] = config('week_rate');
        $config['week_use_time'] = explode('|', config('week_use_time'));
        $config['week_position'] = config('week_position');
        return $config;
    }
}

if (!function_exists('free_config')) {
    function free_config()
    {
        $config['free_loss'] = explode('|', config('free_loss'));
        $config['free_set'] = explode('|', config('free_set'));
        $config['day_position'] = config('day_position');
        return $config;
    }
}

if (!function_exists('day_config')) {
    function day_config()
    {
        $config['day_loss'] = explode('|', config('day_loss'));
        $config['day_rate'] = config('day_rate');
        $config['day_position'] = config('day_position');
        $config['day_use_time'] = explode('|', config('day_use_time'));
        return $config;
    }
}

if (!function_exists('global_config')) {
    function global_config()
    {
        $config['money_range'] = explode('|', config('money_range'));
        $config['limit_fee'] = config('limit_fee');
        $config['commission'] = config('commission');
        $config['stamp_duty'] = config('stamp_duty');
        $config['transfer_fee'] = config('transfer_fee');
        $config['profit_share'] = config('profit_share');
        $config['stop_fee'] = config('stop_fee');
        $config['stock_count'] = config('stock_count');
        $config['rebate'] = config('rebate');
        return $config;
    }
}

if (!function_exists('getEndDay2')) {
    function getEndDay2($start = 'now', $exception = '')
    {
        $starttime = strtotime($start);
        $weekday = date('N', $starttime);
        $tmpday = date('Y-m-d', $starttime);

        if (is_array($exception)) {
            $bfd = in_array($tmpday, $exception);
        } else {
            $bfd = $exception == $tmpday;
        }

        if ($weekday <= 5 && !$bfd) {
            $status = 1;
        } else {
            $status = 2;
        }

        return $status;
    }
}

if (!function_exists('festival')) {
    function festival()
    {
        $t0 = date('Y', time());
        $data = cache('festival' . $t0);

        if ($data) {
            return $data;
        } else {
            $hello = array();
            $d0 = config('legal_holiday');

            if (empty($d0)) {
                $url = 'http://tool.bitefu.net/jiari/?d=' . $t0;
                $d0 = file_get_contents($url);
                $d = json_decode($d0);

                if (is_object($d->{$t0})) {
                    $n = 0;

                    foreach ($d->{$t0} as $key => $value) {
                        $hello[$n] = $key;
                        $n++;
                    }
                } else {
                    $hello = $d->{$t0};
                }
            } else {
                $d = json_decode($d0);
                $hello = $d->{$t0};
            }

            cache('festival' . $t0, $hello);
            return $hello;
        }
    }
}

if (!function_exists('calculate_rate')) {
    function calculate_rate($multiple, $rate, $type, $deposit_money, $endTime)
    {
        if ($type == 1 || $type == 2) {
            $duration = 0;
            $durationTmp = ceil(($endTime - mktime(0, 0)) / 3600 / 24);
            $durationDays = array();

            for ($i = 0; $i < $durationTmp; $i++) {
                $durationDays[$i] = date('Y-m-d', strtotime('+' . $i . ' day'));
            }

            if ($type == 1) {
                $hello = festival();

                foreach ($durationDays as $v) {
                    if (getEndDay2($v, $hello) == 1) {
                        $duration++;
                    }
                }
            }

            if ($type == 2) {
                $duration = round($durationTmp / 7, 2);
            }
            $fee = round($deposit_money * $multiple * $duration * $rate / 100, 2);
        } else {
            //$durationTmp = ceil(($endTime - mktime(0, 0)) / 3600 / 24);
            $durationTmp = ($endTime - time()) / 3600 / 24;
            $duration = round($durationTmp / 30, 2);
            //	dump($duration);
            //	dump($durationTmp);
            //	dump($duration);
            $fee = round($deposit_money * $multiple * $rate / 100, 2);
            if ($duration > 0) {
                $fee = round($fee * $duration, 2);
            }
        }


        return $fee;
    }
}

if (!function_exists('getEndDay')) {
    function getEndDay($start = 'now', $offset = 0, $exception = '')
    {
        $starttime = strtotime($start);
        $endtime = $starttime + $offset * 24 * 3600;
        $end = date('Y-m-d', $endtime);
        $weekday = date('N', $starttime);
        $newoffset = 0;

        for ($i = 1; $i <= $offset; $i++) {
            $today = date('md', $starttime + $i * 24 * 3600);

            switch (($weekday + $i) % 7) {
                case 6:
                    $newoffset += 1;
                    break;

                case 0:
                    $newoffset += 1;
                    break;

                default:
                    if (is_array($exception)) {
                        if (in_array($today, $exception)) {
                            $newoffset += 1;
                        }
                    } else if ($today == $exception) {
                        $newoffset += 1;
                    }

                    break;
            }
        }
        if (0 < $newoffset) {
            return getEndDay($end, $newoffset, $exception);
        } else {
            return $end;
        }
    }

    if (!function_exists('z_market')) {
        function z_market($code)
        {
            $res = \think\Db::name('admin_config')->where(array('name' => 'market_data_in'))->value('value');

            switch ($res) {
                case 1:
                    $res = qq_market($code);
                    $data = qq_to_api($res);
                    break;

                case 2:
                    $res = sina_market($code);
                    $data = sina_to_api($res);
                    break;

                case 3:
                    $res = gs('market', array($code));

                    if (empty($res['error'])) {
                        $data = $res[0];
                    } else {
                        $data = $res['error'];
                    }

                    break;

                default:
                    $res = qq_market($code);
                    $data = qq_to_api($res);
                    break;
            }

            return $data;
        }
    }

    if (!function_exists('z_market_bat')) {
        function z_market_bat($code)
        {
            $d = '';
            $data = array();
            $res = \think\Db::name('admin_config')->where(array('name' => 'market_data_in'))->value('value');

            switch ($res) {
                case 1:
                    $res = explode(',', $code);
                    $count = count($res);

                    foreach ($res as $v) {
                        $d .= fenxi($v) . ',';
                    }

                    $tmd = qq_market_b($d);

                    if (empty($tmd)) {
                        break;
                    }

                    for ($i = 0; $i < $count; $i++) {
                        $k = $i * 53;

                        for ($n = 1; $n <= 53; $n++) {
                            $num = $n + $k;
                            $data[$i][$n] = $tmd[$num];
                        }

                        $data[$i][0] = '';
                        $data[$i] = qq_to_api($data[$i]);
                    }

                    break;

                case 2:
                    $res = explode(',', $code);
                    $count = count($res);

                    foreach ($res as $v) {
                        $d .= fenxi($v) . ',';
                    }

                    $tmd = sina_market_b($d);

                    if (empty($tmd)) {
                        break;
                    }

                    for ($i = 0; $i < $count; $i++) {
                        $k = $i * 32;

                        for ($n = 0; $n < 32; $n++) {
                            $num = $n + $k;
                            $data[$i][$n] = $tmd[$num];
                        }

                        list($tmp) = explode(';', $data[$i][0]);
                        $data[$i][0] = substr($tmp, 11, 8);
                        $data[$i][32] = substr($tmp, 21);

                        $data[$i] = sina_to_api_b($data[$i]);
                    }

                    break;

                case 3:
                    $res = gs('market_bat', array($code));

                    if (!empty($res['error'])) {
                        $data = $res['error'];
                        break;
                    }

                    if (is_array($res)) {
                        unset($res[0]);
                        $count = count($res);

                        for ($i = 0; $i < $count; $i++) {
                            $data[$i] = api_filter($res[$i + 1]);
                        }
                    }

                    break;

                default:
                    $res = explode(',', $code);
                    $count = count($res);

                    foreach ($res as $v) {
                        $d .= fenxi($v) . ',';
                    }

                    $tmd = qq_market_b($d);

                    for ($i = 0; $i < $count; $i++) {
                        $k = $i * 53;

                        for ($n = 1; $n <= 53; $n++) {
                            $num = $n + $k;
                            $data[$i][$n] = $tmd[$num];
                        }

                        $data[$i][0] = '';
                        $data[$i] = qq_to_api($data[$i]);
                    }

                    break;
            }

            return $data;
        }
    }

    if (!function_exists('sohu_keyword')) {
        function sohu_keyword($key)
        {
            $e = preg_match('/^[\\x{4E00}-\\x{9FA5}]+$/u', $key);

            if ($e) {
                return '';
            }

            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'http://q.stock.sohu.com/app1/stockSearch?method=search&callback=&type=cnwbj&sTypeId=15,16&keyword=' . $key . '&_=0.4941991283558309');
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            $output = curl_exec($ch);
            curl_close($ch);
            $t2 = substr(mb_convert_encoding($output, 'utf-8', 'gbk'), 42, -5);
            $t3 = explode('],["', $t2);
            $res = array();

            foreach ($t3 as $k => $v) {
                $tmd = explode(',', $v);

                if ($tmd[0] == '') {
                    $res[$k] = '';
                    continue;
                }

                if (strlen($key) === 6) {
                    if ($tmd[6] != '15') {
                        $res[$k] = '';
                        continue;
                    }

                    $res[0]['code'] = substr($tmd[0], 3, -1);
                    $res[0]['name'] = substr($tmd[2], 1, -1);
                    $res[0]['pin'] = substr($tmd[3], 1, -1);
                } else {
                    $res[$k]['code'] = substr($tmd[0], 3, -1);
                    $res[$k]['name'] = substr($tmd[2], 1, -1);
                    $res[$k]['pin'] = substr($tmd[3], 1, -1);
                }
            }

            ksort($res);
            return $res;
        }
    }

    if (!function_exists('sina_market_b')) {
        function sina_market_b($code)
        {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'http://hq.sinajs.cn/list=' . $code);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            $output = curl_exec($ch);
            curl_close($ch);
            $t2 = explode(';', mb_convert_encoding($output, 'utf-8', 'gbk'));
            $res = [];

            foreach ($t2 as $k => $v) {
                if (strlen($v) == 1) continue;
                $temp = trim(ltrim($v), "\"");
                $res[] = trim($temp, ",");

            }
            $resutData = [];
            foreach ($res as $k => $v) {
                $arr = explode(',', $v);
                unset($arr[32]);

                $resutData = array_merge($resutData, $arr);
            }

            return $resutData;
        }
    }


    if (!function_exists('sina_market')) {
        function sina_market($code)
        {
            $d = fenxi($code);
            $randm = time() . mt_rand(100, 999);
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'http://hq.sinajs.cn/rn=' . $randm . '&list=' . $d . ',' . $d . '_i');
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            $output = curl_exec($ch);
            curl_close($ch);
            $pos = strpos($output, '=') + 2;
            $output = substr($output, $pos, -3);
            $t2 = explode(',', mb_convert_encoding($output, 'utf-8', 'gbk'));
            $t2[32] = $t2[0];
            $t2[0] = $d;
            return $t2;
        }
    }

    if (!function_exists('qq_market')) {
        function qq_market($code)
        {
            $d = fenxi($code);
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'http://qt.gtimg.cn/q=' . $d);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            $output = curl_exec($ch);
            curl_close($ch);
            $t2 = explode('~', mb_convert_encoding($output, 'utf-8', 'gbk'));
            $t2[0] = substr($t2[0], 2, 8);
            return $t2;
        }
    }

    if (!function_exists('z_minute_k')) {
        function z_minute_k($code)
        {
            $res = \think\Db::name('admin_config')->where(array('name' => 'market_data_in'))->value('value');

            switch ($res) {
                case 1:
                    $data = qq_minute_k($code);
                    break;

                case 2:
                    $data = wy_minute_k($code);
                    break;

                case 3:
                    $data = api_minute_k($code);
                    break;

                default:
                    $data = qq_minute_k($code);
                    break;
            }

            return $data;
        }
    }

    if (!function_exists('z_day_k')) {
        function z_day_k($code)
        {
            $res = \think\Db::name('admin_config')->where(array('name' => 'market_data_in'))->value('value');

            switch ($res) {
                case 1:
                    $data = qq_day_k($code);
                    break;

                case 2:
                    $data = sina_day_k($code);
                    break;

                case 3:
                    $data = api_k($code, 5);
                    break;

                default:
                    $data = qq_day_k($code);
                    break;
            }

            return $data;
        }
    }

    if (!function_exists('z_week_k')) {
        function z_week_k($code)
        {
            $res = \think\Db::name('admin_config')->where(array('name' => 'market_data_in'))->value('value');

            switch ($res) {
                case 1:
                    $data = qq_week_k($code);
                    break;

                case 2:
                    $data = sina_week_k($code);
                    break;

                case 3:
                    $data = api_k($code, 6);
                    break;

                default:
                    $data = qq_week_k($code);
                    break;
            }

            return $data;
        }
    }

    if (!function_exists('z_month_k')) {
        function z_month_k($code)
        {
            $res = \think\Db::name('admin_config')->where(array('name' => 'market_data_in'))->value('value');

            switch ($res) {
                case 1:
                    $data = qq_month_k($code);
                    break;

                case 2:
                    $data = sina_month_k($code);
                    break;

                case 3:
                    $data = api_k($code, 7);
                    break;

                default:
                    $data = qq_month_k($code);
                    break;
            }

            return $data;
        }
    }

    if (!function_exists('api_minute_k')) {
        function api_minute_k($code)
        {
            if ($code === 'sh000001') {
                $code = '999999';
            }

            $tmd = gs('TimeData', $code);
            unset($tmd[0]);
            $time = strtotime(date('y-m-d 09:29:00', time()));
            $res = array();

            foreach ($tmd as $k => $v) {
                if ($k == 122) {
                    $time = $time + 5400;
                }

                $res[$k - 1]['time'] = date('Hi', $time + $k * 60);
                $res[$k - 1]['price'] = $v[0];
                $res[$k - 1]['volume'] = $v[1];
            }

            return $res;
        }
    }

    if (!function_exists('api_k')) {
        function api_k($code, $period)
        {
            $index = 0;

            if ($code === 'sh000001') {
                $code = '999999';
                $index = 1;
            }

            if ($code === '399001' || $code === '399006') {
                $index = 1;
            }

            $tmd = gs('GetBar', array($code, $period, $index));
            unset($tmd[0]);
            $res = array();

            foreach ($tmd as $k => $v) {
                $res[$k - 1]['time'] = substr($v[0], 2);
                $res[$k - 1]['open'] = substr($v[1], 0, -4);
                $res[$k - 1]['close'] = substr($v[2], 0, -4);
                $res[$k - 1]['high'] = substr($v[3], 0, -4);
                $res[$k - 1]['low'] = substr($v[4], 0, -4);
                $res[$k - 1]['volume'] = substr($v[5], 0, -2);
            }

            return $res;
        }
    }

    if (!function_exists('qq_minute_k')) {
        function qq_minute_k($code)
        {
            $d = fenxi($code);
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'http://data.gtimg.cn/flashdata/hushen/minute/' . $d . '.js');
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            $output = curl_exec($ch);
            curl_close($ch);
            $t2 = explode('\\n\\', mb_convert_encoding($output, 'utf-8', 'gbk'));
            $count = count($t2);
            unset($t2[0]);
            unset($t2[1]);
            unset($t2[$count - 1]);

            foreach ($t2 as $k => $v) {
                $t2[$k - 2] = explode(' ', trim($v));
            }

            unset($t2[$count - 2]);
            unset($t2[$count - 3]);
            ksort($t2);
            $res = array();

            foreach ($t2 as $k => $v) {
                $res[$k]['time'] = $v[0];
                $res[$k]['price'] = $v[1];
                $res[$k]['volume'] = $v[2];
            }

            $ret = array();

            foreach ($res as $k => $v) {
                $ret[$k]['time'] = $res[$k]['time'];
                $ret[$k]['price'] = $res[$k]['price'];

                if ($k == 0) {
                    $ret[$k]['volume'] = $res[$k]['volume'];
                    continue;
                }

                $ret[$k]['volume'] = (string)($res[$k]['volume'] - $res[$k - 1]['volume']);
            }

            return $ret;
        }
    }

    if (!function_exists('z_search_keyword')) {
        function z_search_keyword($key)
        {
            $res = \think\Db::name('admin_config')->where(array('name' => 'market_data_in'))->value('value');

            switch ($res) {
                case 1:
                    $data = qq_keyword($key);
                    break;

                case 2:
                    $data = sina_keyword($key);
                    break;

                case 3:
                    $data = wy_keyword($key);
                    break;

                default:
                    $data = qq_keyword($key);
                    break;
            }

            return $data;
        }
    }

    if (!function_exists('wy_keyword')) {
        function wy_keyword($key)
        {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'http://quotes.money.163.com/stocksearch/json.do?type=&count=10&word=' . $key . '&t=0.599924786016345');
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            $output = curl_exec($ch);
            curl_close($ch);
            $t2 = json_decode(substr($output, 27, -1));
            $res = array();

            if (empty($t2)) {
                return $res;
            }

            foreach ($t2 as $k => $v) {
                $res[$k]['code'] = $v->symbol;
                $res[$k]['name'] = $v->name;
                $res[$k]['pin'] = $v->spell;
            }

            return $res;
        }
    }

    if (!function_exists('qq_keyword')) {
        function qq_keyword($key)
        {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'http://smartbox.gtimg.cn/s3/?v=2&q=' . $key . '&t=all');
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            $output = curl_exec($ch);
            curl_close($ch);
            $output = preg_replace_callback('#\\\\u([0-9a-f]+)#i', function ($m) {
                return mb_convert_encoding(pack('H4', $m[1]), 'UTF-8', 'UCS-2');
            }, $output);
            $t2 = substr($output, 8, -1);

            if ($t2 == 'N"') {
                return '';
            }

            $t3 = explode('^', $t2);
            $res = array();

            foreach ($t3 as $k => $v) {
                $tmd = explode('~', $v);
                $res[$k]['code'] = $tmd[1];
                $res[$k]['name'] = $tmd[2];
                $res[$k]['pin'] = $tmd[3];
            }

            return $res;
        }
    }

    if (!function_exists('hx_keyword')) {
        function hx_keyword($key)
        {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'http://so.hexun.com/ajax.do?key=' . $key . '&type=stock?math=0.4235173752531409');
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            $output = curl_exec($ch);
            curl_close($ch);
            $t2 = substr(mb_convert_encoding($output, 'utf-8', 'gbk'), 19);
            $t2 = json_decode($t2);
            $res = array();

            foreach ($t2 as $k => $v) {
                $res[$k]['code'] = $v->code;
                $res[$k]['name'] = $v->name;
                $res[$k]['pin'] = $v->pinyin;
            }

            return $res;
        }
    }

    if (!function_exists('jyj_keyword')) {
        function jyj_keyword($key)
        {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'http://code.jrjimg.cn/code?1=1&item=10&areapri=cn|hk|us|stb|ylbtg&typepri=s|w|i|f|b.hg&key=' . $key . '&d=131149');
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            $output = curl_exec($ch);
            curl_close($ch);
            $t2 = substr(mb_convert_encoding($output, 'utf-8', 'gbk'), 26, -63);
            $t3 = explode('},{', $t2);
            $res = array();

            foreach ($t3 as $k => $v) {
                $tmd = explode('",', $v);
                list(, $res[$k]['code']) = explode(':"', $tmd[1]);
                list(, $res[$k]['name']) = explode(':"', $tmd[2]);
                list(, $res[$k]['pin']) = explode(':"', $tmd[3]);
            }

            return $res;
        }
    }

    if (!function_exists('api_keyword')) {
        function api_keyword($key)
        {
            $res = array();

            if (preg_match('/\\d/', $key)) {
                $res = gs('SearchByCode', array($Name = $key));
            }

            if (preg_match('/[A-Za-z]/', $key)) {
                $res = gs('searchByName', array($Name = $key));
            }

            if (0 < preg_match('/[\\x{4e00}-\\x{9fa5}]/u', $key)) {
                $res = gs('searchByName', array($Name = $key));
            }

            return $res;
        }
    }

    if (!function_exists('')) {
        function sina_keyword($key)
        {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'http://suggest3.sinajs.cn/suggest/type=&key=' . $key . '&name=suggestdata_' . time());
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            $output = curl_exec($ch);
            curl_close($ch);
            $t2 = substr(mb_convert_encoding($output, 'utf-8', 'gbk'), 28, -3);
            $t3 = explode(';', $t2);
            $res = array();

            foreach ($t3 as $k => $v) {
                $tmd = explode(',', $v);

                if ($tmd[1] != '31') {
                    $res[$k]['code'] = $tmd[2];
                    $res[$k]['name'] = $tmd[4];
                    $res[$k]['pin'] = strtoupper($tmd[5]);
                }
            }

            return $res;
        }
    }

    if (!function_exists('')) {
        function qq_month_k($code)
        {
            $d = fenxi($code);
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'http://data.gtimg.cn/flashdata/hushen/latest/monthly/' . $d . '.js');
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            $output = curl_exec($ch);
            curl_close($ch);
            $t2 = explode('\\n\\', mb_convert_encoding($output, 'utf-8', 'gbk'));
            $count = count($t2);
            unset($t2[0]);
            unset($t2[1]);
            unset($t2[$count - 1]);

            foreach ($t2 as $k => $v) {
                $t2[$k - 2] = explode(' ', trim($v));
            }

            unset($t2[$count - 2]);
            unset($t2[$count - 3]);
            ksort($t2);
            $res = array();

            foreach ($t2 as $k => $v) {
                $res[$k]['time'] = $v[0];
                $res[$k]['open'] = $v[1];
                $res[$k]['close'] = $v[2];
                $res[$k]['high'] = $v[3];
                $res[$k]['low'] = $v[4];
                $res[$k]['volume'] = $v[5];
            }

            return $res;
        }
    }

    if (!function_exists('')) {
        function qq_week_k($code)
        {
            $d = fenxi($code);
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'http://data.gtimg.cn/flashdata/hushen/latest/weekly/' . $d . '.js');
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            $output = curl_exec($ch);
            curl_close($ch);
            $t2 = explode('\\n\\', mb_convert_encoding($output, 'utf-8', 'gbk'));
            $count = count($t2);
            unset($t2[0]);
            unset($t2[1]);
            unset($t2[$count - 1]);

            foreach ($t2 as $k => $v) {
                $t2[$k - 2] = explode(' ', trim($v));
            }

            unset($t2[$count - 2]);
            unset($t2[$count - 3]);
            ksort($t2);
            $res = array();

            foreach ($t2 as $k => $v) {
                $res[$k]['time'] = $v[0];
                $res[$k]['open'] = $v[1];
                $res[$k]['close'] = $v[2];
                $res[$k]['high'] = $v[3];
                $res[$k]['low'] = $v[4];
                $res[$k]['volume'] = $v[5];
            }

            return $res;
        }
    }

    if (!function_exists('')) {
        function fenxi($code)
        {
            switch (substr($code, 0, 1)) {
                case '0':
                    $d = 'sz' . $code;
                    break;

                case '3':
                    $d = 'sz' . $code;
                    break;

                case '1':
                    $d = 'sz' . $code;
                    break;

                case '2':
                    $d = 'sz' . $code;
                    break;

                case '6':
                    $d = 'sh' . $code;
                    break;

                case '5':
                    $d = 'sh' . $code;
                    break;

                case '9':
                    $d = 'sh' . $code;
                    break;

                default:
                    $d = $code;
                    break;
            }

            return $d;
        }
    }

    if (!function_exists('object2array')) {
        function object2array($object)
        {
            $array = array();

            if (is_object($object)) {
                foreach ($object as $key => $value) {
                    $array[$key] = $value;
                }
            } else {
                $array = $object;
            }

            return $array;
        }
    }

    if (!function_exists('wy_minute_k')) {
        function wy_minute_k($code)
        {
            switch (substr($code, 0, 1)) {
                case '0':
                    $d = '1' . $code;
                    break;

                case '3':
                    $d = '1' . $code;
                    break;

                case '6':
                    $d = '0' . $code;
                    break;

                case 's':
                    $d = '0' . substr($code, 2);
                    break;

                default:
                    $d = $code;
                    break;
            }

            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'http://img1.money.126.net/data/hs/time/today/' . $d . '.json');
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            $output = curl_exec($ch);
            curl_close($ch);
            $tmd = json_decode($output)->data;
            $res = array();

            foreach ($tmd as $k => $v) {
                $res[$k]['time'] = $v[0];
                $res[$k]['price'] = $v[1];
                $res[$k]['volume'] = round($v[3] / 100, 0);
            }

            return $res;
        }
    }

    if (!function_exists('sina_day_k')) {
        function sina_day_k($code)
        {
            $d = fenxi($code);
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'http://money.finance.sina.com.cn/quotes_service/api/json_v2.php/CN_MarketData.getKLineData?symbol=' . $d . '&scale=240&ma=no&datalen=100');
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            $output = curl_exec($ch);
            curl_close($ch);
            $output = substr($output, 2);
            $output = substr($output, 0, -3);
            $t2 = explode('},{', $output);
            $res = array();

            foreach ($t2 as $k => $v) {
                $tmd = explode(',', $v);
                $res[$k]['time'] = date('ymd', strtotime(substr($tmd[0], 5, -1)));
                $res[$k]['open'] = substr($tmd[1], 6, -2);
                $res[$k]['high'] = substr($tmd[2], 6, -2);
                $res[$k]['low'] = substr($tmd[3], 5, -2);
                $res[$k]['close'] = substr($tmd[4], 7, -2);
                $res[$k]['volume'] = substr($tmd[5], 8, -3);
            }

            return $res;
        }
    }

    if (!function_exists('sina_week_k')) {
        function sina_week_k($code)
        {
            $d = fenxi($code);
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'http://money.finance.sina.com.cn/quotes_service/api/json_v2.php/CN_MarketData.getKLineData?symbol=' . $d . '&scale=1200&ma=no&datalen=100');
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            $output = curl_exec($ch);
            curl_close($ch);
            $output = substr($output, 2);
            $output = substr($output, 0, -3);
            $t2 = explode('},{', $output);
            $res = array();

            foreach ($t2 as $k => $v) {
                $tmd = explode(',', $v);
                $res[$k]['time'] = date('ymd', strtotime(substr($tmd[0], 5, -1)));
                $res[$k]['open'] = substr($tmd[1], 6, -2);
                $res[$k]['high'] = substr($tmd[2], 6, -2);
                $res[$k]['low'] = substr($tmd[3], 5, -2);
                $res[$k]['close'] = substr($tmd[4], 7, -2);
                $res[$k]['volume'] = substr($tmd[5], 8, -3);
            }

            return $res;
        }
    }

    if (!function_exists('sina_month_k')) {
        function sina_month_k($code)
        {
            $d = fenxi($code);
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'http://money.finance.sina.com.cn/quotes_service/api/json_v2.php/CN_MarketData.getKLineData?symbol=' . $d . '&scale=7200&ma=no&datalen=100');
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            $output = curl_exec($ch);
            curl_close($ch);
            $output = substr($output, 2);
            $output = substr($output, 0, -3);
            $t2 = explode('},{', $output);
            $res = array();

            foreach ($t2 as $k => $v) {
                $tmd = explode(',', $v);
                $res[$k]['time'] = date('ymd', strtotime(substr($tmd[0], 5, -1)));
                $res[$k]['open'] = substr($tmd[1], 6, -2);
                $res[$k]['high'] = substr($tmd[2], 6, -2);
                $res[$k]['low'] = substr($tmd[3], 5, -2);
                $res[$k]['close'] = substr($tmd[4], 7, -2);
                $res[$k]['volume'] = substr($tmd[5], 8, -3);
            }

            return $res;
        }
    }

    if (!function_exists('qq_day_k')) {
        function qq_day_k($code)
        {
            $d = fenxi($code);
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'http://data.gtimg.cn/flashdata/hushen/latest/daily/' . $d . '.js?maxage=43201&visitDstTime=1');
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            $output = curl_exec($ch);
            curl_close($ch);
            $t2 = explode('\\n\\', mb_convert_encoding($output, 'utf-8', 'gbk'));
            $count = count($t2);
            unset($t2[0]);
            unset($t2[1]);
            unset($t2[$count - 1]);

            foreach ($t2 as $k => $v) {
                $t2[$k - 2] = explode(' ', trim($v));
            }

            unset($t2[$count - 2]);
            unset($t2[$count - 3]);
            ksort($t2);
            $res = array();

            foreach ($t2 as $k => $v) {
                $res[$k]['time'] = $v[0];
                $res[$k]['open'] = $v[1];
                $res[$k]['close'] = $v[2];
                $res[$k]['high'] = $v[3];
                $res[$k]['low'] = $v[4];
                $res[$k]['volume'] = $v[5];
            }

            return $res;
        }
    }

    if (!function_exists('qq_market_b')) {
        function qq_market_b($code)
        {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'http://qt.gtimg.cn/q=' . $code);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            $output = curl_exec($ch);
            curl_close($ch);
            $t2 = explode('~', mb_convert_encoding($output, 'utf-8', 'gbk'));
            unset($t2[0]);
            return $t2;
        }
    }

    if (!function_exists('qq_to_api')) {
        function qq_to_api($res)
        {
            if (substr($res[0], 0, 2) === 'sh') {
                $res[40] = '1';
            } else {
                $res[40] = '0';
            }

            if (mktime(15, 0) < time()) {
                $time = date('H:i:s', mktime(15, 0, 0));
            } else {
                $time = date('H:i:s', time());
            }

            return array('code' => $res[2], 'name' => $res[1], 'yesterday_price' => $res[4], 'open_price' => $res[5], 'national_debt' => '0.00', 'current_price' => $res[3], 'buy_one_price' => $res[9], 'buy_two_price' => $res[11], 'buy_three_price' => $res[13], 'buy_one_amount' => $res[10], 'buy_two_amount' => $res[12], 'buy_three_amount' => $res[14], 'sell_one_price' => $res[19], 'sell_two_price' => $res[21], 'sell_three_price' => $res[23], 'sell_one_amount' => $res[20], 'sell_two_amount' => $res[22], 'sell_three_amount' => $res[24], 'buy_four_price' => $res[15], 'buy_five_price' => $res[17], 'buy_four_amount' => $res[16], 'buy_five_amount' => $res[18], 'sell_four_price' => $res[25], 'sell_five_price' => $res[27], 'sell_four_amount' => $res[26], 'sell_five_amount' => $res[28], 'exchange_code' => $res[40], 'mini_trans' => 100, 'buy_chang_price' => '0.01', 'sell_chang_price' => '0.01', 'type' => 1, 'currency' => 0, 'debt_sign' => 255, 'info' => '', 'highest' => $res[41], 'lowest' => $res[42], 'volume' => $res[36], 'turnover' => $res[37], 'time' => $time, 'turnover_rate' => $res[38], 'pe_ratio' => $res[39], 'circulation_market_value' => $res[44], 'total_market_value' => $res[45], 'pb_ratio' => $res[46]);
        }
    }

    if (!function_exists('sina_to_api')) {
        function sina_to_api($res)
        {
            if (substr($res[0], 0, 2) === 'sh') {
                $res[53] = '1';
            } else {
                $res[53] = '0';
            }

            return array('code' => substr($res[0], 2), 'name' => $res[32], 'yesterday_price' => $res[2], 'open_price' => $res[1], 'national_debt' => '0.00', 'current_price' => $res[3], 'buy_one_price' => $res[11], 'buy_two_price' => $res[13], 'buy_three_price' => $res[15], 'buy_one_amount' => substr($res[10], 0, -2), 'buy_two_amount' => substr($res[12], 0, -2), 'buy_three_amount' => substr($res[14], 0, -2), 'sell_one_price' => $res[21], 'sell_two_price' => $res[23], 'sell_three_price' => $res[25], 'sell_one_amount' => substr($res[20], 0, -2), 'sell_two_amount' => substr($res[22], 0, -2), 'sell_three_amount' => substr($res[24], 0, -2), 'buy_four_price' => $res[17], 'buy_five_price' => $res[19], 'buy_four_amount' => substr($res[16], 0, -2), 'buy_five_amount' => substr($res[18], 0, -2), 'sell_four_price' => $res[27], 'sell_five_price' => $res[29], 'sell_four_amount' => substr($res[26], 0, -2), 'sell_five_amount' => substr($res[28], 0, -2), 'exchange_code' => $res[53], 'mini_trans' => 100, 'buy_chang_price' => '0.01', 'sell_chang_price' => '0.01', 'type' => 1, 'currency' => 0, 'debt_sign' => 255, 'info' => '', 'highest' => $res[4], 'lowest' => $res[5], 'volume' => (string)($res[8] / 100), 'turnover' => (string)($res[9] / 10000), 'time' => $res[31], 'turnover_rate' => (string)round($res[8] / $res[41] / 100, 2), 'pe_ratio' => (string)round($res[3] / $res[34], 2), 'circulation_market_value' => (string)round($res[3] * $res[41] / 10000, 2), 'total_market_value' => (string)round($res[3] * $res[39] / 10000, 2), 'pb_ratio' => (string)round($res[3] / $res[37], 2));
        }
    }

    if (!function_exists('sina_to_api_b')) {
        function sina_to_api_b($res)
        {
            if (substr($res[0], 0, 2) === 'sh') {
                $res[53] = '1';
            } else {
                $res[53] = '0';
            }

            return array('code' => substr($res[0], 2), 'name' => $res[32], 'yesterday_price' => $res[2], 'open_price' => $res[1], 'national_debt' => '0.00', 'current_price' => $res[3], 'buy_one_price' => $res[11], 'buy_two_price' => $res[13], 'buy_three_price' => $res[15], 'buy_one_amount' => substr($res[10], 0, -2), 'buy_two_amount' => substr($res[12], 0, -2), 'buy_three_amount' => substr($res[14], 0, -2), 'sell_one_price' => $res[21], 'sell_two_price' => $res[23], 'sell_three_price' => $res[25], 'sell_one_amount' => substr($res[20], 0, -2), 'sell_two_amount' => substr($res[22], 0, -2), 'sell_three_amount' => substr($res[24], 0, -2), 'buy_four_price' => $res[17], 'buy_five_price' => $res[19], 'buy_four_amount' => substr($res[16], 0, -2), 'buy_five_amount' => substr($res[18], 0, -2), 'sell_four_price' => $res[27], 'sell_five_price' => $res[29], 'sell_four_amount' => substr($res[26], 0, -2), 'sell_five_amount' => substr($res[28], 0, -2), 'exchange_code' => $res[53], 'mini_trans' => 100, 'buy_chang_price' => '0.01', 'sell_chang_price' => '0.01', 'type' => 1, 'currency' => 0, 'debt_sign' => 255, 'info' => '', 'highest' => $res[4], 'lowest' => $res[5], 'volume' => (string)($res[8] / 100), 'turnover' => (string)($res[9] / 10000), 'time' => $res[31]);
        }
    }

    if (!function_exists('api_filter')) {
        function api_filter($res)
        {
            return array('code' => $res[0], 'name' => $res[1], 'yesterday_price' => $res[2], 'open_price' => $res[3], 'national_debt' => $res[4], 'current_price' => $res[5], 'buy_one_price' => $res[6], 'buy_two_price' => $res[7], 'buy_three_price' => $res[8], 'buy_one_amount' => $res[9], 'buy_two_amount' => $res[10], 'buy_three_amount' => $res[11], 'sell_one_price' => $res[12], 'sell_two_price' => $res[13], 'sell_three_price' => $res[14], 'sell_one_amount' => $res[15], 'sell_two_amount' => $res[16], 'sell_three_amount' => $res[17], 'buy_four_price' => $res[18], 'buy_five_price' => $res[19], 'buy_four_amount' => $res[20], 'buy_five_amount' => $res[21], 'sell_four_price' => $res[22], 'sell_five_price' => $res[23], 'sell_four_amount' => $res[24], 'sell_five_amount' => $res[25], 'exchange_code' => $res[26], 'mini_trans' => $res[27], 'buy_chang_price' => $res[28], 'sell_chang_price' => $res[29], 'type' => $res[30], 'currency' => $res[31], 'debt_sign' => $res[32], 'info' => $res[33]);
        }
    }

    if (!function_exists('time_check')) {
        function time_check()
        {
            $tim = time() - strtotime(date('y-m-d 00:00:00', time()));
            if (54000 <= $tim || $tim <= 34200) {
                return false;
            }

            if (41400 <= $tim && $tim <= 46800) {
                return false;
            }

            return true;
        }
    }

    if (!function_exists('data_auth_sign')) {
        /*
         * 数据签名认证
         * @param array $data 被认证的数据
         * @author 绿麻雀
         * @return string
         */
        function data_auth_sign($data = [])
        {
            // 数据类型检测
            if(!is_array($data)){
                $data = (array)$data;
            }

            // 排序
            ksort($data);
            // url编码并生成query字符串
            $code = http_build_query($data);
            // 生成签名
            $sign = sha1($code);
            return $sign;
        }
    }

    if(!function_exists('check_sms_code')){
        /*
         * 检测手机短信验证码
         * @param $mobile 手机号
         * @param bool|false $code
         * @return bool
         * @author menghui
         */
        function check_sms_code($mobile, $code = false)
        {
            if (!$mobile) return false;
            if ($code === false) {   //判断60秒以内是否重复发送
                if (!think\cache::has('sms_'.$mobile) && !think\cache::has('sms_ip') &&(think\cache::get('sms_ip')['ip'] != get_client_ip())) return true;
                if (think\cache::get('sms_'.$mobile)['time']+60 < time()) {
                    if(think\cache::get('sms_ip')['ip'] == get_client_ip()) {
                        return false;
                    }
                    return true;
                } else {
                    return false;
                }
            } else {  //判断验证码是否输入正确
                if (!think\cache::has('sms_'.$mobile)) return false;
                if (think\cache::get('sms_'.$mobile)['code'] == md5($code)) {
                    think\cache::get('sms_'.$mobile)['code'] = '';
                    return true;
                } else {
                    return false;
                }
            }
            return true;
        }

    }

    if (!function_exists('time_check')) {
        function microtime_float()
        {
            list($usec, $sec) = explode(' ', microtime());
            return (double)$usec + (double)$sec;
        }
    }

    if (!function_exists('http')) {
        function http()
        {
            return empty($_SERVER['HTTP_X_CLIENT_PROTO']) ? 'http://' : $_SERVER['HTTP_X_CLIENT_PROTO'] . '://';
        }
    }

    if (!function_exists('sinahy')) {
        function sinahy()
        {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'http://vip.stock.finance.sina.com.cn/q/view/newSinaHy.php');
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            $output = curl_exec($ch);
            curl_close($ch);
            $findme = '{"';
            $pos = strpos($output, $findme) + 2;
            $output = substr($output, $pos, -2);
            $t2 = explode('","', mb_convert_encoding($output, 'utf-8', 'gbk'));
            $res = array();

            foreach ($t2 as $k => $v) {
                /* [31m * TODO SEPARATE[0m */
                $res[$k] = explode(',', substr(explode(':', $v)[1], 1));
            }

            return $res;
        }
    }

    if (!function_exists('qqtop10')) {
        function qqtop10()
        {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'http://qt.gtimg.cn/?q=bkqt_top10');
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            $output = curl_exec($ch);
            curl_close($ch);
            $findme = '="';
            $pos = strpos($output, $findme) + 2;
            $output = substr($output, $pos, -1);
            $t2 = explode('^', mb_convert_encoding($output, 'utf-8', 'gbk'));
            $res = array();

            foreach ($t2 as $k => $v) {
                $res[$k] = explode('~', $v);
            }

            return $res;
        }
    }

    if (!function_exists('qqbot10')) {
        function qqbot10()
        {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'http://qt.gtimg.cn/?q=bkqt_bot10');
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            $output = curl_exec($ch);
            curl_close($ch);
            $findme = '="';
            $pos = strpos($output, $findme) + 2;
            $output = substr($output, $pos, -1);
            $t2 = explode('^', mb_convert_encoding($output, 'utf-8', 'gbk'));
            $res = array();

            foreach ($t2 as $k => $v) {
                $res[$k] = explode('~', $v);
            }

            return $res;
        }
    }

    if (!function_exists('sinabot10')) {
        function sinabot10()
        {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'http://hq.sinajs.cn/rn=1528781824076&format=text&list=sinaindustry_down');
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            $output = curl_exec($ch);
            curl_close($ch);
            $findme = '=[';
            $pos = strpos($output, $findme) + 3;
            $output = substr($output, $pos, -3);
            $t2 = explode('\',\'', mb_convert_encoding($output, 'utf-8', 'gbk'));
            $res = array();

            foreach ($t2 as $k => $v) {
                $res[$k] = explode(',', $v);
            }

            return $res;
        }
    }

    if (!function_exists('sinatop10')) {
        function sinatop10()
        {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'http://hq.sinajs.cn/rn=1528781848576&format=text&list=sinaindustry_up');
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            $output = curl_exec($ch);
            curl_close($ch);
            $findme = '=[';
            $pos = strpos($output, $findme) + 3;
            $output = substr($output, $pos, -3);
            $t2 = explode('\',\'', mb_convert_encoding($output, 'utf-8', 'gbk'));
            $res = array();

            foreach ($t2 as $k => $v) {
                $res[$k] = explode(',', $v);
            }

            return $res;
        }
    }

    if (!function_exists('z_top10')) {
        function z_top10()
        {
            $ret = 2;
            $data = array();

            switch ($ret) {
                case 1:
                    $data = qqtop10();

                    foreach ($data as $k => $v) {
                        unset($data[$k][8]);
                    }

                    $res = $data;
                    break;

                case 2:
                    $data = sinatop10();

                    foreach ($data as $k => $v) {
                        $res[$k][0] = $v[0];
                        $res[$k][1] = $v[1];
                        $res[$k][2] = $v[2];
                        $res[$k][3] = $v[3];
                        $res[$k][4] = $v[5];
                        $res[$k][5] = $v[6];
                        $res[$k][6] = $v[7];
                        $res[$k][7] = $v[8];
                    }

                    break;

                case 3:
                    $data = qqtop10();

                    foreach ($data as $k => $v) {
                        unset($data[$k][8]);
                    }

                    $res = $data;
                    break;

                default:
                    $data = qqtop10();

                    foreach ($data as $k => $v) {
                        unset($data[$k][8]);
                    }

                    $res = $data;
                    break;
            }

            return $res;
        }
    }

    if (!function_exists('z_bot10')) {
        function z_bot10()
        {
            $ret = 2;
            $data = array();

            switch ($ret) {
                case 1:
                    $data = qqbot10();

                    foreach ($data as $k => $v) {
                        unset($data[$k][8]);
                    }

                    $res = $data;
                    break;

                case 2:
                    $data = sinabot10();

                    foreach ($data as $k => $v) {
                        $res[$k][0] = $v[0];
                        $res[$k][1] = $v[1];
                        $res[$k][2] = $v[2];
                        $res[$k][3] = $v[3];
                        $res[$k][4] = $v[5];
                        $res[$k][5] = $v[6];
                        $res[$k][6] = $v[7];
                        $res[$k][7] = $v[8];
                    }

                    break;

                case 3:
                    $data = qqbot10();

                    foreach ($data as $k => $v) {
                        unset($data[$k][8]);
                    }

                    $res = $data;
                    break;

                default:
                    $data = qqbot10();

                    foreach ($data as $k => $v) {
                        unset($data[$k][8]);
                    }

                    $res = $data;
                    break;
            }

            return $res;
        }
    }

    if (!function_exists('sina_stock_top10')) {
        function sina_stock_top10()
        {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'http://vip.stock.finance.sina.com.cn/quotes_service/api/json_v2.php/Market_Center.getHQNodeData?page=1&num=10&sort=changepercent&asc=0&node=hs_a&symbol=&_s_r_a=setlen');
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            $output = curl_exec($ch);
            curl_close($ch);
            $findme = '[';
            $pos = strpos($output, $findme) + 2;
            $output = substr($output, $pos, -2);
            $t2 = explode('},{', mb_convert_encoding($output, 'utf-8', 'gbk'));
            $res = array();
            $ret = array();

            foreach ($t2 as $k => $v) {
                $findme = '",buy:"';
                $pos = strpos($v, $findme);
                $v = substr($v, 0, $pos);
                $res[$k] = explode('",', $v);

                foreach ($res[$k] as $key => $value) {
                    $res[$k][$key] = explode(':"', $value);
                    $ret[$k][$res[$k][$key][0]] = $res[$k][$key][1];
                }

                unset($ret[$k]['pricechange']);
                unset($ret[$k]['symbol']);
            }

            return $ret;
        }
    }

    if (!function_exists('qq_stock_top')) {
        function qq_stock_top($page = 1, $num = 20, $asc = 0)
        {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'http://stock.gtimg.cn/data/view/rank.php?t=ranka/chr&p=' . $page . '&o=' . $asc . '&l=' . $num . '&v=list_data');
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            $output = curl_exec($ch);
            curl_close($ch);
            $num = strpos($output, 'data:\'') + 6;
            $code = substr($output, $num, -3);
            $data = z_market_bat($code);
            $res = array();

            foreach ($data as $k => $v) {
                $res[$k]['code'] = $v['code'];
                $res[$k]['name'] = $v['name'];
                $res[$k]['trade'] = $v['current_price'];
                $res[$k]['changepercent'] = (string)round(($v['current_price'] - $v['yesterday_price']) / $v['yesterday_price'] * 100, 1);
            }

            return $res;
        }
    }

    if (!function_exists('sina_stock_top')) {
        function sina_stock_top($page = 1, $num = 20, $asc = 0)
        {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'http://vip.stock.finance.sina.com.cn/quotes_service/api/json_v2.php/Market_Center.getHQNodeData?page=' . $page . '&num=' . $num . '&sort=changepercent&asc=' . $asc . '&node=hs_a&symbol=&_s_r_a=setlen');
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            $output = curl_exec($ch);
            curl_close($ch);
            $findme = '[';
            $pos = strpos($output, $findme) + 2;
            $output = substr($output, $pos, -2);
            $t2 = explode('},{', mb_convert_encoding($output, 'utf-8', 'gbk'));
            $res = array();
            $ret = array();

            foreach ($t2 as $k => $v) {
                $findme = '",buy:"';
                $pos = strpos($v, $findme);
                $v = substr($v, 0, $pos);
                $res[$k] = explode('",', $v);

                foreach ($res[$k] as $key => $value) {
                    $res[$k][$key] = explode(':"', $value);
                    $ret[$k][$res[$k][$key][0]] = $res[$k][$key][1];
                }

                unset($ret[$k]['pricechange']);
                unset($ret[$k]['symbol']);
            }

            return $ret;
        }
    }

    if (!function_exists('sina_stock_bot10')) {
        function sina_stock_bot10()
        {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'http://vip.stock.finance.sina.com.cn/quotes_service/api/json_v2.php/Market_Center.getHQNodeData?page=1&num=10&sort=changepercent&asc=1&node=hs_a&symbol=&_s_r_a=setlen');
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            $output = curl_exec($ch);
            curl_close($ch);
            $findme = '[';
            $pos = strpos($output, $findme) + 2;
            $output = substr($output, $pos, -2);
            $t2 = explode('},{', mb_convert_encoding($output, 'utf-8', 'gbk'));
            $res = array();
            $ret = array();

            foreach ($t2 as $k => $v) {
                $findme = '",buy:"';
                $pos = strpos($v, $findme);
                $v = substr($v, 0, $pos);
                $res[$k] = explode('",', $v);

                foreach ($res[$k] as $key => $value) {
                    $res[$k][$key] = explode(':"', $value);
                    $ret[$k][$res[$k][$key][0]] = $res[$k][$key][1];
                }

                unset($ret[$k]['pricechange']);
                unset($ret[$k]['symbol']);
            }

            return $ret;
        }
    }

    if (!function_exists('qq_stock_top10')) {
        function qq_stock_top10()
        {
            $time = time() . rand(100, 999);
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'http://qt.gtimg.cn/?q=azdftop10&_=' . $time);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            $output = curl_exec($ch);
            curl_close($ch);
            $findme = '="';
            $pos = strpos($output, $findme) + 2;
            $output = substr($output, $pos, -4);
            $t2 = explode('^', mb_convert_encoding($output, 'utf-8', 'gbk'));
            $ret = array();

            foreach ($t2 as $k => $v) {
                $t2[$k] = explode('~', $v);
                $ret[$k]['code'] = $t2[$k][3];
                $ret[$k]['name'] = $t2[$k][0];
                $ret[$k]['trade'] = $t2[$k][1];
                $ret[$k]['changepercent'] = $t2[$k][2];
            }

            return $ret;
        }
    }

    if (!function_exists('qq_stock_bot10')) {
        function qq_stock_bot10()
        {
            $time = time() . rand(100, 999);
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'http://qt.gtimg.cn/?q=azdfend10&_=' . $time);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            $output = curl_exec($ch);
            curl_close($ch);
            $findme = '="';
            $pos = strpos($output, $findme) + 2;
            $output = substr($output, $pos, -4);
            $t2 = explode('^', mb_convert_encoding($output, 'utf-8', 'gbk'));
            $ret = array();

            foreach ($t2 as $k => $v) {
                $t2[$k] = explode('~', $v);
                $ret[$k]['code'] = $t2[$k][3];
                $ret[$k]['name'] = $t2[$k][0];
                $ret[$k]['trade'] = $t2[$k][1];
                $ret[$k]['changepercent'] = $t2[$k][2];
            }

            return $ret;
        }
    }

    if (!function_exists('z_stock_top10')) {
        function z_stock_top10()
        {
            $ret = \think\Db::name('admin_config')->where(array('name' => 'market_data_in'))->value('value');

            switch ($ret) {
                case 1:
                    $data = qq_stock_top10();
                    break;

                case 2:
                    $data = sina_stock_top10();
                    break;

                case 3:
                    $data = qq_stock_top10();
                    break;

                default:
                    $data = qq_stock_top10();
                    break;
            }

            return $data;
        }
    }

    if (!function_exists('z_stock_bot10')) {
        function z_stock_bot10()
        {
            $ret = \think\Db::name('admin_config')->where(array('name' => 'market_data_in'))->value('value');

            switch ($ret) {
                case 1:
                    $data = qq_stock_bot10();
                    break;

                case 2:
                    $data = sina_stock_bot10();
                    break;

                case 3:
                    $data = qq_stock_bot10();
                    break;

                default:
                    $data = qq_stock_bot10();
                    break;
            }

            return $data;
        }
    }

    //记录操作日志
    if (!function_exists('addlog')) {
        function addlog($username = '系统操作', $action = '', $content = '')
        {
            $record['username'] = $username;
            $record['action'] = $action;
            $record['content'] = $content;
            $record['addtime'] = time();
            $record['ip'] = get_client_ip(1);
            Db::name('log')->insert($record);


        }
    }
}


/**
 * ajax_return				Ajax方式返回数据到客户端
 * @param   array  	$data  	要返回的数据
 * @param   string  $type  	AJAX返回数据格式
 * @param 	return 	void 	结果集
 */
function ajax_return($status = 1, $msg = '', $data = '') {
    //返回数据
    $token = md5(date("Y-m-d H:i:s") . rand_code(6));
    $return = array(
        'status' => $status,
        'msg' => $msg,
        'data' => $data,
//        'token' => $token
    );
    // 默认返回JSON数据格式到客户端 包含状态信息
    header('Content-Type:application/json; charset=utf-8');
    exit(json_encode($return, JSON_UNESCAPED_UNICODE));
}

/**
 * dump 					打印变量
 * @param 	mixed 	$var	变量
 * @return 	void			无返回结果
 */
function dump($var) {
    ob_start();
    var_dump($var);
    $output = ob_get_clean();
    $output = preg_replace('/\]\=\>\n(\s+)/m', '] => ', $output);
    $output = '<pre>' . htmlspecialchars($output, ENT_QUOTES) . '</pre>';
    echo($output);
}

/*
 * 验证身份证号
 * */
function is_idcard( $id )
{
    $id = strtoupper($id);
    $regx = "/(^\d{15}$)|(^\d{17}([0-9]|X)$)/";
    $arr_split = array();
    if(!preg_match($regx, $id))
    {
        return FALSE;
    }
    if(15==strlen($id)) //检查15位
    {
        $regx = "/^(\d{6})+(\d{2})+(\d{2})+(\d{2})+(\d{3})$/";

        @preg_match($regx, $id, $arr_split);
        //检查生日日期是否正确
        $dtm_birth = "19".$arr_split[2] . '/' . $arr_split[3]. '/' .$arr_split[4];
        if(!strtotime($dtm_birth))
        {
            return FALSE;
        } else {
            return TRUE;
        }
    }
    else      //检查18位
    {
        $regx = "/^(\d{6})+(\d{4})+(\d{2})+(\d{2})+(\d{3})([0-9]|X)$/";
        @preg_match($regx, $id, $arr_split);
        $dtm_birth = $arr_split[2] . '/' . $arr_split[3]. '/' .$arr_split[4];
        if(!strtotime($dtm_birth)) //检查生日日期是否正确
        {
            return FALSE;
        }
        else
        {
            //检验18位身份证的校验码是否正确。
            //校验位按照ISO 7064:1983.MOD 11-2的规定生成，X可以认为是数字10。
            $arr_int = array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
            $arr_ch = array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');
            $sign = 0;
            for ( $i = 0; $i < 17; $i++ )
            {
                $b = (int) $id{$i};
                $w = $arr_int[$i];
                $sign += $b * $w;
            }
            $n = $sign % 11;
            $val_num = $arr_ch[$n];
            if ($val_num != substr($id,17, 1))
            {
                return FALSE;
            } //phpfensi.com
            else
            {
                return TRUE;
            }
        }
    }
}

/**
 * redirect					网址重定向
 * @param	string	$uri	要跳转的网址
 * @param	string	$method	跳转方法
 * @param	int		$code	状态码
 */
function redirect($uri = '', $method = 'auto', $code = null) {
    if (isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') !== FALSE) {
        $method = 'refresh';
    } elseif ($method !== 'refresh' && (empty($code) || ! is_numeric($code))) {
        if (isset($_SERVER['SERVER_PROTOCOL'], $_SERVER['REQUEST_METHOD']) && $_SERVER['SERVER_PROTOCOL'] === 'HTTP/1.1') {
            $code = ($_SERVER['REQUEST_METHOD'] !== 'GET')
                ? 303	// reference: http://en.wikipedia.org/wiki/Post/Redirect/Get
                : 307;
        } else {
            $code = 302;
        }
    }
    if ($GLOBALS['module'] != DEFAULT_MODULE) {
        $uri = "/" . $GLOBALS['module'] . $uri;
    }
    if ('refresh' == $method) {
        header('Refresh:0;url='.$uri);
    } else {
        header('Location: '.$uri, true, $code);
    }
    exit;
}

/**
 * rand_code					生成随机码
 * @param  int		$len 		随机码长度
 * @param  string 	$type 		随机码类型：num-数字，str-小写字母，astr-大写字母，both-小写字母和数字，all-全部字符
 * @return string 	$result 	返回随机码
 */
function rand_code($len = 6, $type = 'num') {
    $result = '';
    $num = '0123456789';
    $str = 'abcdefghijklmnopqrstuvwxyz';
    $astr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $typelist = array(
        'num' => $num,
        'str' => $str,
        'astr' => $astr,
        'both' => $str . $num,
        'all' => $astr . $str . $num
    );
    for($i = 0; $i < $len; $i++) {
        $result .= substr($typelist[$type], mt_rand(0, strlen($typelist[$type]) - 1 ) , 1);
    }
    return $result;
}

/**
 * clear_cache 			更新缓存（仅删除runtime目录下所有文件。保留runtime目录）
 * @return 	void		无返回内容：cache-系统缓存目录，logs-系统错误目录，runtime-编译目录，session-session目录
 */
function clear_cache($directory = "") {
    if (is_dir($directory) == false) {
        return false;
    }
    $handle = opendir($directory);
    while (($file = readdir($handle)) !== false) {
        if ($file != "." && $file != "..") {
            is_dir("$directory/$file") ? clear_cache("$directory/$file") : unlink("$directory/$file");
        }
    }
    if (readdir($handle) == false) {
        closedir($handle);
        rmdir($directory);
    }
    return true;
}

/**
 * get_client_ip			获取客户端IP地址
 * @param integer $type 	返回类型：0-返回IP地址，1-返回IPV4地址数字
 * @return string			返回结果集
 */
function get_client_ip($type = 1)
{
    $ip = "";
    if (isset($_SERVER['HTTP_X_CLIENTIP'])) {
        $ip = $_SERVER['HTTP_X_CLIENTIP'];
    } elseif (isset ( $_SERVER ['HTTP_X_FORWARDED_FOR'] )) {
        $arr = explode ( ',', $_SERVER ['HTTP_X_FORWARDED_FOR'] );
        $pos = array_search ( 'unknown', $arr );
        if (false !== $pos)
            unset ( $arr [$pos] );
        $ip = trim ( $arr [0] );
    } elseif (isset ( $_SERVER ['HTTP_CLIENT_IP'] )) {
        $ip = $_SERVER ['HTTP_CLIENT_IP'];
    } elseif (isset ( $_SERVER ['REMOTE_ADDR'] )) {
        $ip = $_SERVER ['REMOTE_ADDR'];
    }elseif (isset($_SERVER['HTTP_X_CLIENTIP'])&&isset ( $_SERVER ['REMOTE_ADDR'] )) {
        $ip = $_SERVER ['HTTP_X_CLIENTIP'];
    }elseif (isset($_SERVER['HTTP_X_REAL_IP'])&&isset ( $_SERVER ['HTTP_X_CLIENTIP'] )) {
        $ip = $_SERVER ['HTTP_X_REAL_IP'];
    }
    if ($ip == "::1") $ip = "127.0.0.1";
    if ($type == 1) {
        return ip2long($ip);
    } else {
        return $ip;
    }
}

/**
 * msubstr 						截取字符串长度函数
 * @param 	string 	$string 	需要处理字符串
 * @param 	int 	$length 	处理长度
 * @param 	string 	$ellipsis 	隐藏的省略样式
 * @return 	void|string			返回结果集
 */
function msubstr($string, $length = 0, $ellipsis = '...', $strip = 0) {
    $string = htmlspecialchars_decode($string);
    $string = str_ireplace('<br />', PHP_EOL, $string);
    $string = str_ireplace('<br/>', PHP_EOL, $string);
    $string = str_ireplace('<br>', PHP_EOL, $string);
    //剥去字符串中的 HTML、XML 以及 PHP 的标签。
    $string = strip_tags($string);
    if ($strip == 1) {
        //换行替换为空格
        $string = str_replace(PHP_EOL, ' ', $string);
    } else {
        $string = str_replace(PHP_EOL, '<br />', $string);
    }

    $len = 0;
    $res = '';
    for ($i = 0; $i < mb_strlen($string); $i++) {
        $word = mb_substr($string, $i, 1);
        if (strlen($word) == 1) {
            $len += strlen($word);
        } else {
            $len += strlen($word) - 1;
        }
        if ($len < $length) {
            $res .= $word;
        } else {
            break;
        }
    }
    //过滤不完整的标签
    $end = strrpos($res, "<");
    if ($end) {
        if (strpos($res, ">", $end) === false) {
            $res = substr($res, 0, $end);
        }
    }
    //如果没有完整输出则加上 ...
    if ($length < strlen($string)) {
        $res .= $ellipsis;
    }
    return $res;
}

/**
 * format_time					日期格式化   判断时间是否是今天，如果是今天只返回时间，不返回日期
 * @param 	date 	$time  		格式要求Y-m-d H:i:s 或者时间戳格式
 * @param 	int 	$date_type  输出时间格式：1-显示短日期：“8-21”；“9：00”； 2-时间差格式：“3天前”；“2小时前”
 * @param 	string	$result 	返回的格式 Y   m-d   H:i
 **/
function time_format($time, $date_type = 1) {
    $result = '';
    if ($time) {
        //转换为时间戳
        $time_ux = is_numeric($time) ? $time : strtotime($time);
        if ($date_type == 1) {
            // 转换为 YYYY-MM-DD 格式
            $time_day = date('Y-m-d', $time_ux);
            $time_month = date('m', $time_ux);
            $time_year = date('Y', $time_ux);
            // 获取今天的 YYYY-MM-DD 格式
            if ($time_day == date('Y-m-d')) {
                //当天
                $result = date('H:i', $time_ux);
            } elseif ($time_year == date('Y')) {
                //本年
                $result = date('m-d',$time_ux);
            } else {
                //其他年份
                $result = date('Y',$time_ux);
            }
        } elseif ($date_type == 2) {
            if (date('Y-m-d', $time_ux) == date('Y-m-d')) {
                //今天
                $timediff = floor((time() - $time_ux) / 60); //时间差：分钟
                if ($timediff > 59) {
                    $result = floor($timediff / 60) . "小时前";
                } elseif ($timediff > 0) {
                    $result = $timediff . "分钟前";
                } else {
                    $result = "刚刚";
                }
            } elseif (date('Y-m-d', $time_ux + 86400) == date('Y-m-d')) {
                $result = "昨天";
            } elseif (date('Y-m-d', $time_ux + 86400 * 2) == date('Y-m-d')) {
                $result = "前天";
            } else {
                $timediff = floor((time() - $time_ux) / 86400); //时间差：天
                if ($timediff > 365) {
                    $result = floor($timediff / 365) . "年前";
                } elseif ($timediff > 30) {
                    $result = floor($timediff / 30) . "个月前";
                } else {
                    $result = $timediff . "天前";
                }
            }
        }
    }
    return $result;
}

//判断是PC端访问还是移动端访问
function is_mobile() {
    $user_agent = strtolower($_SERVER['HTTP_USER_AGENT']);
    $mobile_type = array('iphone', 'ipad', 'ipod', 'windows mobile', 'windows phone', 'windows ce', 'android', 'blackberry', 'bb10', 'maemo');
    $is_mobile = false;
    foreach ($mobile_type as $m) {
        if (false !== strpos($user_agent, $m)) {
            $is_mobile = true;
            break;
        }
    }
    if ($is_mobile) {
        return true;
    } else {
        return false;
    }
}

/**
 * sql_format				格式化插入数据库的短字符串（用于用户名、usercode、邮箱等）
 * @param 	string $str 	要转换的字符串
 * @return 	string $str		返回结果集
 */
function sql_format($str) {
    //过滤用户输入
    $str = urldecode($str);
    $str = str_format_filter($str);
    //删除非法字符
    $str = str_replace("'", "", $str);
    $str = str_replace("&", "", $str);
    $str = str_replace("=", "", $str);
    $str = str_replace("\"", "", $str);
    $str = str_replace("\\", "", $str);

    return $str;
}
/**
 * str_format_filter		字符串过滤函数
 * @param 	string $str 	要过滤的字符串
 * @return 	string $str		返回结果集
 */
function str_format_filter($str) {
    //转换空格
    $str = str_replace("　", " ", $str); //全角空格
    $str = str_replace(" ", " ", $str); //一个奇怪的空格符
    $str = str_replace(chr(9), " ", $str); //制表符
    //特殊符号
    $arr = array(
        '＜' => '《',
        '＞' => '》',
        '〝' => '“',
        '〞' => '”',
        '′' => "'",
        '﹙' => '（',
        '﹚' => '）',
        '\\' => '' //过滤转义字符
    );
    $str = strtr($str, $arr);

    //html转义字符
    $str = str_ireplace("&amp;", "&", $str);
    $str = str_ireplace("&nbsp;", " ", $str);
    $str = str_ireplace("&quot;", "\"", $str);
    $str = str_ireplace("&lt;", "<", $str);
    $str = str_ireplace("&gt;", ">", $str);
    $str = str_ireplace("&#8206;", "", $str);

    //删除多余空格
    $str = preg_replace('/\s+/', ' ', $str);

    //删除多余单引号
    $str = preg_replace("/\'+/", "'", $str);

    //过滤字符串首尾空格
    $str = trim($str);

    return $str;
}

/**
 * @access chk_phone			验证手机号
 * @param int 	$mobile 	 	手机号码
 * @param return boolean 		结果集：true-正确，false-错误
 */
function chk_phone($mobile = "") {
    if (preg_match("/^1[34578]{1}\d{9}$/", $mobile)) {
        return true;
    } else {
        return false;
    }
}


/**
 * 分页页码显示
 * @access page_format			数据分页
 * @param int 	$total 	 		记录总数，
 * @param int 	$pagesize	 	每页条数。
 * @param int 	$p				当前页码
 * @param string 	$url	 	跳转url
 */
function page_format($total = 0, $pagesize = 20, $p = 1, $url = "") {
    $url =  "/" . $GLOBALS['module'] . $url;
    $url = str_replace(" ", "", $url);
    $page_show = "";
    $p = (int)$p; //当前页
    $total = (int)$total;
    $pagesize = (int)$pagesize;
    if ($p < 1) $p = 1;
    $pend = ceil($total / $pagesize); //尾页
    if ($pend > 1) {
        $page_show .= "<div class=\"layui-box layui-laypage layui-laypage-default\">";
        if ($p > $pend) $p = $pend;
        $p1 = $p - 4; //开始页码
        if ($p1 < 1) $p1 = 1;
        $p2 = $p + 4; //结束页码
        if ($p2 > $pend) $p2 = $pend;
        if ($p > 1) {
            $page_show .= "<a href=\"" . $url . "\" class=\"laypage_first\">首页</a><a href=\"" . $url . ($p - 1) . "\" class=\"layui-laypage-prev\">上一页</a>";
        }
        for ($i = $p1; $i <= $p2; $i++) {
            if ($i != $p) {
                $page_show .= " <a href=\"" . $url . $i . "\">" . $i . "</a>";
            } else {
                $page_show .= " <span class=\"layui-laypage-curr\"><em class=\"layui-laypage-em\"></em><em>" . $i . "</em></span>";
            }
        }
        if ($p < $pend) {
            $page_show .= " <a href=\"" . $url . ($p + 1) . "\" class=\"layui-laypage-next\">下一页</a> <a href=\"" . $url . $pend . "\" class=\"layui-laypage-last\">尾页</a>";
        }
        $page_show .= "</div>";
    }
    return $page_show;
}

/**
 * send_curl 					模拟post请求(CURL方式)
 * @param 	string 	$url		请求地址
 * @param 	array 	$params 	post键值对数据
 * @return 	string 	$result		返回结果集
 */
function send_curl($url, $params = array()) {
    $curl = curl_init(); // 启动一个CURL会话
    curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址  
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回  
    curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容 
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); //设置为 1 是检查服务器SSL证书中是否存在一个公用名(common name)。译者注：公用名(Common Name)一般来讲就是填写你将要申请SSL证书的域名 (domain)或子域名(sub domain)。 设置成 2，会检查公用名是否存在，并且是否与提供的主机名匹配。 0 为不检查名称。 在生产环境中，这个值应该是 2（默认值）
    curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)'); // 模拟用户使用的浏览器  
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转  
    curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自动设置Referer 
    if ($params){
        curl_setopt($curl, CURLOPT_POST, 1); // 发送一个常规的Post请求
        if (is_array($params)) {
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data); // Post提交的数据包
        }
    }
    curl_setopt($curl, CURLOPT_TIMEOUT, 10); // 设置超时限制防止死循环  
    curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10);
    $res = curl_exec($curl); // 执行操作
    //检查是否404（网页找不到）
    $httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
    curl_close($curl); // 关闭CURL会话
    if($httpcode == 404 || $httpcode == 403) {
        return false;
    }else{
        return $res;
    }
}

/**
 * send_sms 					发送短信(目前使用聚合短信)
 * @param 	int 	$mobile		手机号
 * @param 	var 	$content	短信内容
 * @return 	array	$result		状态：0-失败，1-成功
模版id:33592-温馨提示#code#。如非本人操作，请忽略本短信
模版id:44601-您的验证码是#code#。如非本人操作，请忽略本短信
 */
function send_sms($mobile, $content = "") {
    if (! $content) {
        $content = rand_code();
        $tpl_id = 44601;
    } else {
        $tpl_id = 44606;
    }

    //判断手机号是否为空
    if (! $mobile) {
        $return["status"] = 0;
        $return["msg"] = "手机号码为空";
        return $return;
    }

    //验证手机号
    if (! chk_phone($mobile)) {
        $return["status"] = 0;
        $return["msg"] = "号码不正确";
        return $return;
    }
    //短信接口地址
    $url = 'http://v.juhe.cn/sms/send?mobile=' . urlencode($mobile) . '&tpl_id=' . $tpl_id . '&tpl_value=' . urlencode('#code#=' . $content) . '&key=b7c0a38ad22339be2798ba775d94c5b1';
    $res = send_curl($url);
    $res = json_decode($res, true);
    if (! $res) {
        $return['status'] = 0;
        $return['msg'] = "短信发送失败";
        return $return;
    } else {
        if ($res['error_code'] == 0) {
            //状态为0，说明短信发送成功
            $return['status'] = 1;
            $return['msg'] = "验证码已发送到您的手机，请查看短信";
        } else {
            //错误标识
            $error_code = array(
                "205401" => "错误的手机号码",
                "205402" => "错误的短信模板ID",
                "205403" => "网络错误,请重试",
                "205404" => "发送失败，具体原因请参考返回reason",
                "205405" => "号码异常/同一号码发送次数过于频繁",
                "205406" => "不被支持的模板",
                "10001" => "错误的请求KEY",
                "10002" => "该KEY无请求权限",
                "10003" => "KEY过期",
                "10004" => "错误的OPENID",
                "10005" => "应用未审核超时，请提交认证",
                "10007" => "未知的请求源",
                "10008" => "被禁止的IP",
                "10009" => "被禁止的KEY",
                "10011" => "当前IP请求超过限制",
                "10012" => "请求超过次数限制",
                "10013" => "测试KEY超过请求限制",
                "10014" => "系统内部异常(调用充值类业务时，请务必联系客服或通过订单查询接口检测订单，避免造成损失)",
                "10020" => "接口维护",
                "10021" => "接口停用"
            );
            //状态非0，说明失败
            $return['status'] = 0;
            $return['msg'] = "错误提示:" . $res['error_code'] . "-" . $error_code[$res['error_code']];
        }
        return $return;
    }
}

/**
 * 检测是否开市时间
 * @return 	boolean	 $result 	结果集
 */
function get_holiday() {
    //调试模式不限制
    if (DEVELOPMENT_ENVIRONMENT == false) {
        //上午开市时间
        $am_start = date("09:30");
        $am_end = date("11:30");

        //下午开市时间
        $pm_start = date("13:00");
        $pm_end = date("15:00");

        //当前周期
        $week = date('w');

        //当前时间
        $now = date("H:i");
        $day = date("Ymd");

        //条件 （非星期六和星期天及指定假日）（当前时间>=上午开市时间 与 当前时间 <=上午收市时间）（当前时间>=下午开市时间 与 当前时间 <=下午收市时间）
        if($week == 6 || $week == 0 || $now < $am_start || $now > $pm_end || ($now > $am_end && $now < $pm_start)) {
            return false;
        } else {
            $cache = new Fcache();
            $res = $cache->get("config_holiday");
            if (! $res) {
                global $db;
                $sql = "select * from config_holiday where begin_date <= " . strtotime($day) . " and end_date >= " . strtotime($day);
                $row = $db->query($sql)->row_array();
                if (! $row) {
                    $res = 1;
                } else {
                    $res = 2;
                }
                $cache->set("config_holiday", $res, 86400);
            }
            if ($res == 2) {
                return false;
            }
        }
    }
    //返回结果集
    return true;
}

/**
 * get_stock 					查询股票最新信息（本信息来源：新浪）
 * @param 	array 	$data		股票代码
 * @return 	array	$result		股票最新信息：
key：为股票代码
0："平安银行",股票名字；
1："8.890",今日开盘价；
2："8.910",昨日收盘价；
3："8.740",当前价格；
4："8.890",今日最高价；
5："8.720",今日最低价；
6："8.740",竞买价，即"买一"报价；
7："8.750",竞卖价，即"卖一"报价；
8："69651707",成交的股票数，由于股票交易以一百股为基本单位，所以在使用时，通常把该值除以一百；
9："613783434.310",成交金额，单位为"元"，为了一目了然，通常以"万元"为成交金额的单位，所以通常把该值除以一万；
10："85352",买一申请85352股，即854手；
11："8.740",买一报价；
12："666900",买二申请666900股，即6669手；
13："8.730",买二报价；
14："618974",买三申报618974股，即6190手；
15："8.720",买三报价；
16："740000",买四申报740000股，即7400手；
17："8.710",买四报价；
18："625600",买五申报625600股，即6256手；
19："8.700",买五报价；
20："195502",卖一申报195502股，即1955手；
21："8.750",卖一报价
22："840401",卖二申报840401股，即8404手；
23："8.760",卖二报价
24："70900",卖三申报70900股，即709手；
25："8.770",卖三报价
26："144140",卖四申报144140股，即1441手；
27："8.780",卖四报价
28："135601",卖五申报135601股，即1356手；
29："8.790",卖五报价
30："2017-05-04",日期；
31："15:05:03",时间；
32:	"00"

注：

通用计算规则
涨跌幅：round((当前价 - 昨日收盘价) * 100 / 当前价, 2);
round(($v[3]-$v[2]) * 100 / $v[3], 2);
涨跌:	round(当前价 - 昨日收盘价);
round($v[3]-$v[2], 2);


平台规则：
停牌：	当前价格为0;
$v[3] = 0;
成交量(手):ceil($v[8] / 100);
禁止买入：涨跌幅小于限定值禁止买入；
禁止卖出：手动
可买升：在禁止买入基础上，手动设置
可买跌：在禁止买入基础上，手动设置
关盘：手动
管理费率：0.002
留仓费率：0.0006
印花税率：0.001
买入费率：0.003
卖出费率：0.003

委买股票/市买股票
finance:减少资金额度
amount:减少可用额度

撤销委买/市卖股票
finance:增加资金额度
amount:增加可用额度

买入资金变动规则：
finance:资金余额 = 资金余额 - 买入手续费
amount:最新额度 = 可用额度 - 股票金额 - （ 买入手续费 * 10）
gain:交易盈亏 = 交易盈亏 - 买入手续费

卖出资金变动规则
finance:资金余额 = 资金余额 + 卖出后盈亏 - 卖出手续费 - 印花税 - 管理费
amount:最新额度 = 可用额度 + 股票金额 - （（ 卖出手续费 - 印花税 - 管理费） * 10）
gain:交易盈亏 = 交易盈亏 + 卖出后盈亏 - 卖出手续费 - 印花税 - 管理费

购买股票数量 = 可用额度 / 当前股票价格
买入手续费 = 买入总金额 * 买入费率
卖出手续费 = 卖出总金额 * 卖出费率
管理费 = 卖出总金额 * 管理费率
留仓费 = 留仓费率 * 留仓天数
印花税 = 卖出总金额 * 印花税率
买涨：盈亏 = （卖出价格 - 买入价格）* 数量 - 买入手续费 - 卖出手续费 - 管理费（针对002、300开头股票适用） - 留仓费 - 印花税
买跌：盈亏 = （买入价格 - 卖出价格）* 数量 - 买入手续费 - 卖出手续费 - 管理费（针对002、300开头股票适用） - 留仓费 - 印花税
持股：
可提现金额 = 净资产 - 本金 - 提现申请金额

非持股：
可提现金额 = 资金余额

涨跌幅：round((当前价 - 今日开盘价) * 100 / 当前价, 2);

爆仓： = 保证金率 < 10%
涨跌幅 > 7% 或者 小于 -7%暂停交易

盈亏比例：=（浮动盈亏-所有的手续费用）/ 持仓金额 * 100

注：通常讲的爆仓 当你的资金账户不足于弥补现有交易的损失时，系统会自动帮你进行平仓，也就是经纪商不会为你承担损失。
你的钱不够弥补损失时，经纪商会强行帮你卖掉手中头寸 。
股票中的爆主要是两种
1-单向交易类型
只可以买多，这种爆仓一种是因为配资加了杠杆。
比如：你有一万，但是你申请了4倍的配资，等于是你买了五万的股票。当你的亏损到一万本金时，就会强行平仓。
2 双向交易类型
主要股指期货类型，无论做多还是空，无论配资与否，亏损到本金就会平仓。
总结一句话，就是少于本金，就会爆仓。一般股票买卖不配资，除了退市或者企业倒闭 是不会存在爆仓情况的。
 */
function get_stock($data = array()) {

    //声明变量
    $result = $temp = array();
    if (is_array($data)) {

        //根据数据库所有股票总数量，计算循环次数，循环抓取，一次抓取全部容易失败。
        $count = count($data);//总数量
        $size = 800;//每页数量
        $len = ceil($count / $size);
        //采集股票信息
        for ($i = 1; $i <= $len; $i ++) {
            //分页读取数据
            $start = ($i - 1) * $size;
            $row = array_slice($data, $start, $size);
            $code = implode(",", $row);

            //根据条件抓取内容
            $str = send_curl("http://hq.sinajs.cn/list=" . $code);
            $str = iconv('GBK//IGNORE', 'UTF-8', $str);

            $str = str_ireplace('var hq_str_', '', $str);
            $str = str_ireplace('="', ',', $str);
            $str = str_ireplace(' ', '', $str);
            $str = str_ireplace(chr(13), '', $str);//回车,等价于\r
            $str = str_ireplace(chr(10), '', $str);//换行,等价于\n
            $str = str_ireplace('";', '||', $str);
            $str = trim($str, '||');

            //转为数组
            $res = explode('||', $str);
            $temp = array_merge($temp, $res);
        }
        //格式化采集数据
        foreach ($temp as $key => $val) {
            $k = substr($val, 0, 8);
            $str = substr($val, 9);
            $v = explode(",", $str);
            $result[$k] = $v;
        }
    }
    //返回采集结果
    return $result;
}

/**
 * get_stock1 					    获取最新股票信息（腾讯接口）
 * @return 	array	$result			结果集
 */
function get_stock1($data = array()) {

    //声明变量
    $result = $temp = array();
    if (is_array($data)) {

        //根据数据库所有股票总数量，计算循环次数，循环抓取，一次抓取全部容易失败。
        $count = count($data);//总数量
        $size = 60;//每页数量
        $len = ceil($count / $size);
        //采集股票信息
        for ($i = 1; $i <= $len; $i ++) {
            //分页读取数据
            $start = ($i - 1) * $size;
            $row = array_slice($data, $start, $size);
            $code = implode(",", $row);

            //根据条件抓取内容
            $str = send_curl("http://qt.gtimg.cn/q=" . $code);
            $str = iconv('GBK//IGNORE', 'UTF-8', $str);

            $str = str_ireplace('v_', '', $str);
            $str = str_ireplace('="', '~', $str);
            $str = str_ireplace(' ', '', $str);
            $str = str_ireplace(chr(13), '', $str);//回车,等价于\r
            $str = str_ireplace(chr(10), '', $str);//换行,等价于\n
            $str = str_ireplace('";', '||', $str);
            $str = trim($str, '||');

            //转为数组
            $res = explode('||', $str);
            $temp = array_merge($temp, $res);
        }

        //格式化采集数据
        foreach ($temp as $key => $val) {
            $k = substr($val, 0, 8);
            $str = substr($val, 9);
            $v = explode("~", $str);
            $result[$k] = $v;
        }
    }
    //返回采集结果
    return $result;
}

/**
 * get_new_stock 					检查新股票
 * @return 	array	$result			结果集
 */
function get_new_stock() {
    $msg = '<p class="xinsu-fontcolor-green">[' . date("Y-m-d H:i:s") . '] 更新开始！</p>';
    $str = file_get_contents("http://quote.eastmoney.com/stocklist.html");
    $str = iconv('GBK', 'UTF-8', $str);
    preg_match_all("/<li><a target=\"_blank\" href=\"http:\/\/quote\.eastmoney\.com\/(.+?)\.html\">(.+?)\(\d+\)<\/a><\/li>/is", $str, $res);

    //实例化拼音
    global $db;
    $chs = new Chinese();
    $code = $res[1];
    $name = $res[2];

    //查询所有股票
    $sql = "select *, concat(type, code) stock FROM `stock_code`";
    $stock = $db->query($sql)->result_array();
    if ($stock) $stock = array_column($stock, null, "stock");

    //遍历股票
    $sql1 = $sql = $xdxr = "";
    foreach($code as $key => $val) {
        //截取股票信息
        $stock_code = substr($val, 2);
        $stock_name = trim($name[$key]);
        $stock_type = substr($val, 0, 2);

        //股票拼音简写
        $pinyin = strtolower($chs->getFirstLetter(iconv('UTF-8','GBK', str_replace('*', '', $stock_name))));
        $tmp = substr($stock_code, 0, 1);

        //判断股票类型
        if($tmp == 0 || $tmp == 3 || $tmp == 6) {
            //判断股票是否存在
            if (isset($stock[$val])) {
                if ($stock[$val]["name"] != $stock_name) {
                    $id = $stock[$val]["id"];

                    //判断股票是否除权除息
                    $filed = strtolower(mb_substr($stock_name, 0, 2));
                    if ($filed == 'xd' || $filed == "dr" || $filed == "xr" ) {
                        $open = 0;
                    } else {
                        $open = 1;
                    }

                    //更新名称
                    $sql = "update `stock_code` set name = '{$stock_name}', pinyin = '{$pinyin}', open = $open where id = $id";
                    $db->query($sql);

                    $msg .= '<p class="xinsu-fontcolor-red">[' . date("Y-m-d H:i:s") . ']成功的更新了股票名称:{$stock_code},从【'.$stock[$val]["name"].'】更改成【'.$stock_name.'】</p>';
                    $xdxr .= '[' . date("Y-m-d H:i:s") . ']成功的更新了股票名称:'.$stock_code.',从【'.$stock[$val]["name"].'】更改成【'.$stock_name.'】' . PHP_EOL;
                }
            } else {
                //添加新股
                //$msg .= '<p class="xinsu-fontcolor-green">[' . date("Y-m-d H:i:s") . "]成功添加股票代码:{$stock_code},【{$stock_name}】</p>";
                $sql1 .= ", ('$stock_code', '$stock_name', '$stock_type', '$pinyin')";
            }
        }
    }

    //添加新股
    if ($sql1) {
        $sql1 = trim($sql1, ",");
        $sql = "insert into stock_code (code, name, type, pinyin) values " . $sql1;
        //$db->query($sql);//暂时取消新增股票。
    }
    if ($xdxr) {
        //记录日志
        file_put_contents("./data/logs/get_new_stock.log", $xdxr . PHP_EOL, FILE_APPEND);
    }
    $msg .= '<p>[' . date("Y-m-d H:i:s") . '] 更新完毕！</p>';
    return $msg;
}


function isLogin($token)
{
    if(!empty($token)){
        $decoded = Jwt::decode($token, JWT_TOKEN_KEY, array('HS256'));
        return $decoded->id;
    }else{
        return 0;
    }
}

function getUserInfo($token){
    $user = Jwt::decode($token, JWT_TOKEN_KEY, array('HS256'));
    $user = object2array($user);
    return $user;
}

/**
 * 用户平账
 * @return 	array()	 $result 	结果集
 */
function set_user($uid = 0) {
    if ($uid > 0) {
        global $db;

        //查询充值
        $sql = "SELECT sum(money) c from log_charge where uid = $uid and status = 0";
        $res = $db->query($sql)->row_array();
        $charge = $res["c"];

        //查询提现
        $sql = "SELECT sum(money) c from log_atm where uid = $uid and (ispay = 1 or ispay = 0)";
        $res = $db->query($sql)->row_array();
        $cash = $res["c"];

        //持仓金额
        $sql = "select sum(round((bull_num - sell_num) * bull_price, 2)) as c from `stock_bull` where uid = $uid and can_sell = 1";
        $res = $db->query($sql)->row_array();
        $bull_money = $res["c"];

        //买入手续费
        $sql = "select sum(bull_cost_money) c from `stock_bull` where uid = $uid";
        $res = $db->query($sql)->row_array();
        $bull_cost = $res["c"];


        //卖出手续费
        $sql = "select uid, sum(gain - (cost_money + stamp_money + manage_money + save_money)) c from stock_sell where uid = $uid";
        $res = $db->query($sql)->row_array();
        $sell_cost = $res["c"];

        //查询委托(针对买入)
        $sql = "select sum(round(money * 0.003, 2)) trust_cost, sum(money) trust_money from `stock_trust` where uid = $uid and status = 0 and trust_type = 1";
        $res = $db->query($sql)->row_array();
        $trust_cost = $res["trust_cost"];
        $trust_money = $res["trust_money"];

        //可用保证金
        $finance = $charge - $cash;
        $amount = $finance * 10 - $bull_money - $trust_money;//可用额度 - 持仓金额 - 委托金额

        //总盈亏
        $gain = $sell_cost - $bull_cost - $trust_cost;

        //计算总金额
        $finance = $finance + $gain;
        $amount = $amount + ($gain * 10);

        //返回参数
        $result["id"] = $uid;
        $result["finance"] = round($finance, 2);
        $result["amount"] = round($amount, 2);
        $result["gain"] = round($gain, 2);

        //返回结果集
        return $result;
    } else {
        //返回参数
        $result["id"] = $uid;
        $result["finance"] = 0.00;
        $result["amount"] = 0.00;
        $result["gain"] = 0.00;

        //返回结果集
        return $result;
    }
}

/**
 * get_user 					获取用户资金情况
 * @param 	int 	$uid		用户ID
 * @param 	int 	$type		详情类型0-基本信息，1-详细信息
 * @return 	array	$result		结果集:
finance-资金余额，
amount-可用额度，
bull_money-持仓金额，
total_assets-总资产，
net_assets-净资产，
total_gain-总盈亏，
ratio-保证金率，
cash-可提现金额
 */
function get_user($uid = 0, $type = 0) {
    //初始化连接
    global $db;

    //结果集
    $result = array();

    //判断是多条还是单条
    if (0 < $uid && is_numeric($uid)) {
        //查询用户信息
        $sql = "select id, aid, finance, amount, gain finance_gain, agent_name, staff_name, username, realname, demo_account, reg_date, last_login, mobile, ip, is_locked, is_disable, is_stop, stock_type from user where id = {$uid}";
        $user = $db->query($sql)->row_array();
        if ($user) {
            //用户信息
            $result = $user;

            //详细信息
            //持仓金额
            $result["bull_money"] = 0;

            //查询委托(针对买入)
            $sql = "select sum(money) as c from `stock_trust` where uid = {$uid} and status = 0 and trust_type = 1";
            $res = $db->query($sql)->row_array();
            if ($res) $result["bull_money"] += $res["c"];

            //计算费用（卖出后盈亏，卖出手续费：管理费 + 卖出手续费 + 印花税 + 留仓费）
            $gain = $total_gain = $bull_money = 0;

            //持仓记录
            $sql = "select bull_price, bull_type, bull_time, (bull_num - sell_num) num, stock_code, CONCAT(stock_type, stock_code) as code from `stock_bull` where uid = {$uid} and can_sell = 1";
            $list = $db->query($sql)->result_array();

            //判断是否存在持仓（如果用户持仓，需要计算用户资金动态情况）
            if ($list) {
                //最新价格
                $code = array_column($list, "code");
                $stock_info = get_stock($code);

                //计算费用
                foreach ($list as $key => $val) {
                    $val["price"] = round($stock_info[$val["code"]][3], 2);//当前价格
                    if ($val["price"] <= 0) {
                        //股票停盘交易价格按照昨天收盘价格收盘
                        $val["price"] = round($stock_info[$val["code"]][2], 2);
                    }
                    $sell = common_sell($val);
                    $gain += $sell["gain"];
                    $total_gain += $sell["total_gain"];
                    $bull_money += round($val["bull_price"] * $val["num"], 2);
                }
            }

            //计算结果
            $result["bull_money"] += $bull_money;
            $result["gain"] = $gain;//卖出后浮动总盈亏（不含卖出手续费）
            $result["total_gain"] = $total_gain;//卖出后总浮动盈亏（卖出后盈亏 - 卖出需要的手续费）
            $result["all_gain"] = $result["finance_gain"] + $total_gain;//浮动平台总盈亏（不参与计算，仅作为展示使用）
            $result["total_assets"] = round($result["bull_money"] + $result["amount"] + ($result["total_gain"] * 10), 2);//用户总资产 = 持仓金额 + 可用额度 + （浮盈 * 10）
            $result["net_assets"] = round($result["total_assets"] / 10, 2);//用户净资产 = 用户总资产 / 10

            //判断用户是否持仓
            if ($result["bull_money"] > 0) {
                $result["ratio"] = ((round(($result["finance"] + $result["total_gain"]) / ($result["bull_money"] / 10), 2)) - 0.03) * 100;//保证金率 = （资金余额 - 总浮动盈亏）/（持仓金额除以10）减去0.03预留手续费
                $result["cash"] = min(($result["finance"] + $result["total_gain"]), round($result["amount"] / 10, 2));//提现金额 = 资金余额 - 总浮动盈亏（备注：当保证金大于可用额度，需要可用额度/10与保证金取最小值）

                //保证金系统预留（15%）
                if ($result["ratio"] > 15) {
                    $a = round(($result["cash"] * 100 / $result["ratio"]), 2);
                    $b = ($result["ratio"] - 15) / 100;
                    $result["cash"] = round($a * $b, 2);
                } else {
                    $result["cash"] = 0;
                }
            } else {
                if ($result["finance"] > 0) $result["ratio"] = 100; else $result["ratio"] = 0;
                $result["cash"] = $result["finance"];//可提现金额 = 账户余额
            }

            //格式化可提金额
            $result["cash"] = round($result["cash"], 2);
            if ($result["cash"] < 0) $result["cash"] = 0;
        }
    } else {
        //多条用户
        $sql = "select id, aid, finance, amount, gain finance_gain, agent_name, staff_name, username, realname, demo_account, reg_date, last_login, mobile, ip, is_locked, is_disable, is_stop, stock_type from user where id in ({$uid})";
        $user = $db->query($sql)->result_array();

        //判断用户是否存在
        if ($user) {
            //详细信息
            if ($type == 1) {
                //查询委托(针对买入)
                $sql = "select uid, sum(money) as money from `stock_trust` where uid in ({$uid}) and status = 0 and trust_type = 1 group by uid";
                $trust = $db->query($sql)->result_array();
                if ($trust) {
                    $trust = array_column($trust, "money", "uid");
                }

                //计算费用（卖出后盈亏，卖出手续费：管理费 + 卖出手续费 + 印花税 + 留仓费）
                $tmp = $gain = $total_gain = $bull_money = array();

                //持仓记录
                $sql = "select uid, bull_price, bull_type, bull_time, (bull_num - sell_num) num, stock_code, CONCAT(stock_type, stock_code) as code from `stock_bull` where uid in ({$uid}) and can_sell = 1";
                $bull = $db->query($sql)->result_array();

                //判断是否存在持仓（如果用户持仓，需要计算用户资金动态情况）
                if ($bull) {
                    //最新价格
                    $code = array_column($bull, "code");
                    $stock_info = get_stock($code);

                    //计算费用
                    foreach ($bull as $key => $val) {
                        $val["price"] = round($stock_info[$val["code"]][3], 2);//当前价格
                        if ($val["price"] <= 0) {
                            //股票停盘交易价格按照昨天收盘价格收盘
                            $val["price"] = round($stock_info[$val["code"]][2], 2);
                        }
                        $sell = common_sell($val);
                        if (isset($gain[$val["uid"]])) {
                            $gain[$val["uid"]] += $sell["gain"];
                            $total_gain[$val["uid"]] += $sell["total_gain"];
                            $bull_money[$val["uid"]] += round($val["bull_price"] * $val["num"], 2);
                        } else {
                            $gain[$val["uid"]] = $sell["gain"];
                            $total_gain[$val["uid"]] = $sell["total_gain"];
                            $bull_money[$val["uid"]] = round($val["bull_price"] * $val["num"], 2);
                        }
                    }
                }

                //格式化数据
                foreach ($user as $key => $val) {
                    //基本资料
                    $tmp = $val;

                    //持仓金额
                    $tmp["bull_money"] = 0;
                    if (isset($trust[$val["id"]])) $tmp["bull_money"] += $trust[$val["id"]];
                    if (isset($bull_money[$val["id"]])) $tmp["bull_money"] += $bull_money[$val["id"]];
                    //其他费用
                    $tmp["gain"] = isset($gain[$val["id"]]) ? $gain[$val["id"]] : 0;//卖出后浮动总盈亏（不含卖出手续费）
                    $tmp["total_gain"] = isset($total_gain[$val["id"]]) ? $total_gain[$val["id"]] : 0;//卖出后总浮动盈亏（卖出后盈亏 - 卖出需要的手续费）
                    $tmp["all_gain"] = $val["finance_gain"] + $tmp["total_gain"];//浮动平台总盈亏（不参与计算，仅作为展示使用）
                    $tmp["total_assets"] = round($tmp["bull_money"] + $val["amount"] + ($tmp["total_gain"] * 10), 2);//用户总资产 = 持仓金额 + 可用额度 + （浮盈 * 10）
                    $tmp["net_assets"] = round($tmp["total_assets"] / 10, 2);//用户净资产 = 用户总资产 / 10

                    //判断用户是否持仓
                    if ($tmp["bull_money"] > 0) {
                        $tmp["ratio"] = ((round(($val["finance"] + $tmp["total_gain"]) / ($tmp["bull_money"] / 10), 2)) - 0.03) * 100;//保证金率 = （资金余额 - 总浮动盈亏）/（持仓金额除以10）减去3%预留手续费
                        $tmp["cash"] = min(($val["finance"] + $tmp["total_gain"]), round($val["amount"] / 10, 2));//提现金额 = 资金余额 - 总浮动盈亏（备注：当保证金大于可用额度，需要可用额度/10与保证金取最小值）

                        //保证金系统预留（15%）
                        if ($tmp["ratio"] > 15) {
                            $a = round(($tmp["cash"] * 100 / $tmp["ratio"]), 2);
                            $b = ($tmp["ratio"] - 15) / 100;
                            $tmp["cash"] = round($a * $b, 2);
                        } else {
                            $tmp["cash"] = 0;
                        }
                    } else {
                        if ($val["finance"] > 0) $tmp["ratio"] = 100; else $tmp["ratio"] = 0;
                        $tmp["cash"] = $val["finance"];//可提现金额 = 账户余额
                    }

                    //格式化可提金额
                    $tmp["cash"] = round($tmp["cash"], 2);
                    if ($tmp["cash"] < 0) $tmp["cash"] = 0;

                    //计算结果
                    $result[$val["id"]] = $tmp;
                }
            } else {
                $result = array_column($user, null, "id");
            }
        }
    }
    return $result;
}

/**
 * bull_stock 						买入；（买入股票）
 * @param 	int 	$uid			用户ID
 * @param 	string 	$code			股票代码：纯数字
 * @param 	int 	$num			股票数量：最低100股票
 * @param 	int 	$bull_type		股票类型：1-融资/买升/买多，2-融券/买跌/买空
 * @param 	int 	$bull_price		买入价格：单位（元）
 * @return 	boolean	$result			状态：大于0-失败，0-成功
 */
function bull_stock($uid = 0, $code = "", $num = 0, $bull_type = 1, $bull_price = 0) {
    //设置结果集
    $result["status"] = 0;
    $result["msg"] = "买入失败（100）";

    //获取休市状态
    $holiday = get_holiday();
    if ($holiday == false) {
        return $result;
    }

    //提前停止交易
    $time = time();
    if (DEVELOPMENT_ENVIRONMENT == false && $time >= strtotime(date("14:57"))) {
        $result["msg"] = "系统结算，暂停交易！";
        return $result;
    }

    //接收参数
    $uid = intval($uid);
    $code = sql_format($code);
    $num = intval($num);
    $bull_type = intval($bull_type);
    $bull_price = round($bull_price, 2);

    //设置参数
    if ($bull_type != 1 && $bull_type != 2) $bull_type = 1;
    if ($bull_price < 0) $bull_price = 0;

    //检验参数
    if ($uid < 0 || !$code || $num < 100) {
        $result["msg"] = "参数有误！";
        return $result;
    }

    //检查股票是否可以买入
    if ($num % 100 != 0) {
        $result["msg"] = "股票数量为100倍数";
        return $result;
    }

    //系统设置
    global $db;
    global $config_sys;

    //参数管理 - 判断股票数量是否满足购买条件
    if($num < $config_sys['num_min']) {
        //超出最小限制数量禁止购买
        $result["msg"] = "最低要买入{$config_sys['num_min']}股";
        return $result;
    } elseif ($num > $config_sys['num_max']) {
        //超出最大限制数量禁止购买
        $result["msg"] = "最多可买入{$config_sys['num_max']}股";
        return $result;
    }

    //查询限制股票（每个会员限制股票情况不同）
    $sql = "select * from user_forbid where uid = $uid and code = '$code'";
    $row = $db->query($sql)->row_array();
    if ($row) {
        $result["msg"] = "该股票券源已用完！";
        return $result;
    }

    //股票管理：停牌，禁买，禁买升，禁买跌
    $sql = "select id, type, code, name, open, stop_pai, can_bull, can_bull_up, can_bull_down, concat(type, code) as type_code FROM `stock_code` where code = {$code}";
    $stock = $db->query($sql)->row_array();
    if (! $stock) {
        $result["msg"] = "股票代码有误：{$code}";
        return $result;
    }
    $code = $stock["type_code"];

    //股票管理 - 判断股票是否关盘，禁买升，禁买跌
    if($stock['open'] == 0) {
        //关盘
        $result["msg"] = "该{$code}股票今日除权或除息，限制买入";
        return $result;
    } elseif ($stock['can_bull'] == 0) {
        //关盘
        $result["msg"] = "该{$code}股票已经满仓！<br />“满仓”是指:其他会员购买该只股票数量已经超过800万股无法再买入！（100）";
        return $result;
    } elseif ($stock['can_bull_up'] == 0 && $bull_type == 1) {
        //禁买升
        $result["msg"] = "该{$code}股票已经满仓！<br />“满仓”是指:其他会员购买该只股票数量已经超过800万股无法再买入！（101）";
        return $result;
    } elseif ($stock['can_bull_down'] == 0 && $bull_type == 2) {
        //禁买跌
        $result["msg"] = "该{$code}股票已经满仓！<br />“满仓”是指:其他会员购买该只股票数量已经超过800万股无法再买入！（102）";
        return $result;
    }

    //获取股票信息
    $stock_info = get_stock(array($code));
    $stock_info = $stock_info[$code];
    $price = @round($stock_info[3], 2);//股票当前价格
    $stock_code = $stock["code"];//股票代码
    $stock_type = $stock["type"];//股票类型
    $stock_name = $stock["name"];//股票名字

    //股票管理 - 判断股票是否停牌
    if ($price <= 0) {
        //停盘-禁止购买，更新股票状态;当前股票价格为0，或者当日成交额大于8000万；
        $sql = "update stock_code set stop_pai = 1, stop_date = " . strtotime($stock_info[30] . " " . $stock_info[31]) . " where code = {$stock_code}";
        $db->query($sql);

        //提示禁止买入
        $result["msg"] = "该股票于 " . $stock_info[30] . "开始停牌,7天内不能买卖!";
        return $result;
    } else {
        if ($stock['stop_pai'] == 1) {
            //开牌
            $sql = "update stock_code set stop_pai = 0, stop_date = 0 where code = {$stock_code}";
            $db->query($sql);
        }
    }

    //股票管理 - 涨跌幅-算法3：round((当前价 - 昨日收盘价) * 100 / 昨日收盘价, 2); round(($v[3]-$v[2]) * 100 / $v[2], 2);
    $zdf = round(round($price - $stock_info[2], 2) * 100 / $stock_info[2], 2);

    //股票管理 - 判断是否超出限制涨跌幅
    if(strpos(strtolower($stock['name']), 'st') === false) {
        //如果不是ST股票
        if($zdf >= $config_sys["bull_range_limit"] || $zdf <= - $config_sys["bull_range_limit"]) {
            $result["msg"] = "涨跌幅 " . $zdf . "%，超出{$config_sys["bull_range_limit"]}个点,暂停交易！";
            return $result;
        }
    } else {
        //如果是ST股票
        if($zdf >= $config_sys["st_bull_range_limit"] || $zdf <= -$config_sys["st_bull_range_limit"]) {
            $result["msg"] = "ST涨跌幅 " . $zdf . "%，超出{$config_sys["st_bull_range_limit"]}个点,暂停交易！";
            return $result;
        }
    }

    //买入管理 - 判断是否委托买入
    if ($bull_price > 0) {
        //查询委托表大于指定数量不允许买入
        $sql = "select count(*) as c from `stock_trust` where uid = {$uid} and status = 0 and trust_type = 1";
        $res = $db->query($sql)->row_array();
        $trust_num = $res["c"];

        //委托数量不能超出最大限制
        if ($trust_num > $config_sys["trust_num"]) {
            //提示禁止买入
            $result["msg"] = "委托数量超出限制范围，必须小于数量：" . $config_sys["trust_num"];
            return $result;
        }

        //条件：委托买入，委托价须低于当前市价；委托卖出，委托价须高于当前市价；委托价不能超过最新价的±2%。
        if ($bull_type == 1) {
            //买升
            if ($bull_price > $price) {
                //提示禁止买入
                $result["msg"] = "委托价超出限制范围，必须小于当前价格：{$price}";
                return $result;
            }

            //涨幅
            $zf = ($price - $bull_price) / $price * 100;
            if ($zf > 2) {
                $bull_price = round($price * (1 - 0.02), 2);
                $result["msg"] = "委托价超出范围，最低价为：{$bull_price}";
                return $result;
            }

        } else {
            //买跌
            if ($bull_price < $price) {
                //提示禁止买入
                $result["msg"] = "委托价超出限制范围，必须大于当前价格：{$price}";
                return $result;
            }

            //跌幅
            $zf = ($bull_price - $price) / $price * 100;
            if ($zf > 2) {
                $bull_price = round($price * (1 + 0.02), 2);
                $result["msg"] = "委托价超出范围，最高价为：{$bull_price}";
                return $result;
            }
        }
        $trust_type = 1;//委托买入
    } else {
        $bull_price = $price;
        $trust_type = 0;//市价买入
    }

    //用户管理 - 查询用户信息
    $user = get_user($uid);

    //用户管理 - 用户信息不存在提示禁买
    if (! $user) {
        $result["msg"] = "用户不存在，购买股票失败！";
        return $result;
    }

    //用户管理 - 判断用户状态
    if ($user["is_locked"] == 1 || $user["is_disable"] == 1 || $user["is_stop"] == 1) {
        $result["msg"] = "用户被禁用，暂无执行任何操作！";
        return $result;
    }

    //用户管理 - 判断用户可购买股票限制
    if ($user["stock_type"] > 0) {
        //禁止买升、买多、融资
        if ($user["stock_type"] != $bull_type && $bull_type == 1) {
            $result["msg"] = "禁止购买融资股票";
            return $result;
        }
        //禁止买跌、买空，融券
        if ($user["stock_type"] != $bull_type && $bull_type == 2) {
            $result["msg"] = "禁止购买融券股票";
            return $result;
        }
    }

    //买入管理 - 计算金额，额度，盈亏
    $bull_money = $bull_price * $num;//成交额
    $bull_cost = $config_sys["bull_cost"];//手续费率
    $bull_cost_money = round($bull_money * $bull_cost, 2);//买入手续费
    $amount = $bull_money + ($bull_cost_money * 10);//最新额度 = 股票金额 + （ 买入手续费 * 10）

    //买入管理 - 判断股票资金是否满足购买条件
    if (($user["amount"] - $amount) < 0 || ($user["finance"] - $bull_cost_money) < 0) {
        //超出可用额度禁止购买
        $result["msg"] = "你的可用资金不足!请充值后再来购买！";
        return $result;
    } elseif ($bull_money > $config_sys['money_max']) {
        //单笔额度大于100万，提示不允许买入。
        $result["msg"] = "您的用户交易级别：单笔股票交易额限<font color=red>{$config_sys['money_max']}</font>万。<br />（如需扩大交易金额，请联系工作人员！）";
        return $result;
    } elseif ($bull_money > round($user["amount"] * 0.5, 2)) {
        //单笔股票额度不能大于可用额度的50%
        $result["msg"] = "单笔股票交易额不能超过可用额度50%，请重新确认!";
        return $result;
    } else {
        //查询单股票持仓金额
        $sql = "select sum(round((bull_num - sell_num) * bull_price, 2)) as money from `stock_bull` where uid = $uid and can_sell = 1 and stock_code = {$stock_code} and stock_type = '{$stock_type}'";
        $res = $db->query($sql)->row_array();
        $stock_money = $res["money"];

        //单股持仓总额大于200万，提示不允许买入。
        if (($stock_money + $bull_money) > $config_sys['total_max']) {
            $result["msg"] = "您的用户交易级别：单只股票交易额限<font color=red>{$config_sys['total_max']}</font>万。<br />（如需扩大交易金额，请联系工作人员！）";
            return $result;
        } elseif ($stock_money + $bull_money > round($user["amount"] * 0.5, 2)) {
            //单支股票额度不能大于可用额度的50%
            $result["msg"] = "单支股票交易额不能超过可用额度50%，请重新确认!";
            return $result;
        }
    }

    //买入：委托买入价格不等于市价，进入委托表。否则不进入。
    if ($trust_type == 1) {
        $limit_time=$config_sys['buy_limit_interval'];
        $last_time=time()-$limit_time;
        $last_sql="select  * from stock_trust where stock_trust_time >={$last_time} and aid={$user["aid"]} and uid={$uid} and trust_type=1 order by stock_trust_time desc limit 1";

        $last_list=$db->query($last_sql)->result_array();
        if($last_list){
            //返回结果
            $result["msg"] = "操作频繁，请稍后再试！";
            return $result;
        }
        //委托购买
        $sql = "insert into `stock_trust` (aid, uid, username, stock_type, stock_code, stock_name, bull_type, price, num, money, trust_type, stock_trust_time, stock_deal_time, status) value ({$user["aid"]}, {$uid}, '{$user["username"]}', '{$stock_type}', '{$stock_code}', '{$stock_name}', {$bull_type}, {$bull_price}, {$num}, {$bull_money}, {$trust_type}, {$time}, 0, 0)";
        $db->query($sql);
        if (! $db->affected_rows()) {
            //事务回滚
            $db->trans_rollback();

            //返回结果
            $result["msg"] = "委托失败（100）";
            return $result;
        }

        //更新用户表：更新实际额度，更新盈亏；
        $remark = "限价买入股票(股票名称:{$stock_name},数量:{$num},单价:{$bull_price},金额:{$bull_money},买入手续费:{$bull_cost_money});";
        $res = common_user($uid, -$bull_cost_money, -$amount, -$bull_cost_money, $remark);
        if (! $res) {
            //事务回滚
            $db->trans_rollback();

            //返回结果
            $result["msg"] = "委托失败（101）";
            return $result;
        }

        //委托成功
        $result["status"] = 1;
        $result["msg"] = "已委托";
    } else {
        //开启事务
        $db->trans_begin();
        $limit_time=$config_sys['buy_limit_interval'];
        $last_time=time()-$limit_time;
        $last_sql="select  * from stock_bull where bull_time >={$last_time} and aid={$user["aid"]} and uid={$uid}  order by bull_time desc limit 1";

        $last_list=$db->query($last_sql)->result_array();
        if($last_list){
            //返回结果
            $result["msg"] = "操作频繁，请稍后再试！";
            return $result;
        }
        //市价购买
        $order_no = date("YmdHis") . rand_code(5);
        $sql = "insert into stock_bull (aid, uid, username, stock_code, stock_type, stock_name, bull_type, bull_price, bull_num, bull_money, bull_cost, bull_cost_money, bull_trust_id, bull_trust_time, bull_time, can_sell_num, order_no) values ({$user["aid"]}, {$uid}, '{$user["username"]}', '{$stock_code}', '{$stock_type}', '{$stock_name}', {$bull_type}, {$bull_price}, {$num}, {$bull_money}, {$bull_cost}, {$bull_cost_money}, 0, 0, {$time}, {$num}, {$order_no})";
        $db->query($sql);
        if (! $db->insert_id()) {
            //事务回滚
            $db->trans_rollback();

            //返回结果
            $result["msg"] = "购买失败（100）";
            return $result;
        }

        //更新用户表：更新实际额度，更新盈亏；
        $remark = "市价买入股票(股票名称:{$stock_name},数量:{$num},单价:{$bull_price},金额:{$bull_money},买入手续费:{$bull_cost_money});";
        $res = common_user($uid, -$bull_cost_money, -$amount, -$bull_cost_money, $remark);
        if (! $res) {
            //事务回滚
            $db->trans_rollback();

            //返回结果
            $result["msg"] = "购买失败（101）";
            return $result;
        }

        //提交事务
        $db->trans_commit();

        //购买成功
        $result["status"] = 1;
        $result["msg"] = "购买成功！";
    }


    //返回结果集
    return $result;
}

/**
 * sell_stock 					平仓；（卖出股票）
 * @param 	int 	$id			持仓ID
 * @param 	int 	$num		卖出数量
 * @param 	float 	$sell_price	卖出价格0-市价卖出，大于0-委托卖出
 * @param 	int 	$manage		是否强制卖出：0-否，1-是
 * @return 	array	$result		状态：0-失败，1-成功
 */
function sell_stock($id = 0, $num = 0, $sell_price = 0, $manage = 0) {
    //设置结果集
    $result["status"] = 0;
    $result["msg"] = "卖出失败（100）";

    //提前停止交易
    if (DEVELOPMENT_ENVIRONMENT == false && $manage != 1 && time() >= strtotime(date("Y-m-d 14:57"))) {
        $result["status"] = 0;
        $result["msg"] = "系统结算，暂停交易！";
        return $result;
    }

    //格式化参数
    $sell_price = round($sell_price, 2);
    $num = intval($num);
    $id = intval($id);
    if ($manage != 1) $manage = 0;//0-正常，1-强制

    //获取休市状态
    $holiday = get_holiday();

    //判断参数是否有误
    if ($id > 0 && (($num > 0 && $holiday == true) || $manage == 1)) {
        //判断数量
        if ($num % 100 != 0) {
            $result["status"] = 0;
            $result["msg"] = "股票数量为100倍数";
            return $result;
        }

        //全局参数
        global $db;
        global $config_sys;

        //查询持仓信息
        $sql = "select id bull_id, aid, uid, username, stock_type, stock_code, stock_name, can_sell_num, bull_num, sell_num, bull_type, bull_price, bull_time, concat(stock_type, stock_code) as code from `stock_bull` where id = {$id} and can_sell = 1";
        $row = $db->query($sql)->row_array();

        //持仓单存在
        if ($row) {
            //判断数量（考虑委托部分）
            if ($row["can_sell_num"] < $num) {
                $result["msg"] = "持仓单最多可卖股票数量：{$row["can_sell_num"]}";
                return $result;
            }

            //持仓参数
            $uid = $row["uid"];
            $aid = $row["aid"];
            $bull_id = $row["bull_id"];
            $username = $row["username"];
            $bull_type = $row["bull_type"];//买入股票类型
            $bull_price = $row["bull_price"];//买入价格
            $bull_time = $row["bull_time"];//建仓时间
            $stock_code = $row["stock_code"];//股票代码
            $stock_type = $row["stock_type"];//股票标识
            $stock_name = $row["stock_name"];//股票名称
            $code = $row["code"];//完整股票代码
            $trust_type = 2;
            $now = $stock_trust_time = time();
            $status = $stock_deal_time = 0;

            //判断是否是强制执行
            if ($manage != 1) {
                //计算最低卖出股票时间
                if ($bull_type == 1) {
                    //融资/买升/买多
                    $sell_time = $config_sys["sell_min_time"];//融资最小卖出时间
                } else {
                    //融券/买跌/买空
                    $sell_time = $config_sys["r_sell_min_time"];//融券最小卖出时间
                }

                //判断股票是否可以卖出
                if ($now - $bull_time < $sell_time * 60) {
                    //提示禁止卖出
                    $result["msg"] = "该股票最低卖出时间：" . $sell_time . "分钟！";
                    return $result;
                }

                //查询股票信息
                $sql = "select id, code, name, type, open, stop_pai, can_sell FROM `stock_code` where code = '{$stock_code}' and type = '{$stock_type}'";
                $stock = $db->query($sql)->row_array();
                if (! $stock) {
                    $result["msg"] = "股票代码有误：{$code}";
                    return $result;
                }

                //判断股票是否停牌，禁卖
                if ($stock['open'] == 0) {
                    //关盘
                    $result["msg"] = "该{$code}股票今日除权或除息，限制卖出";
                    return $result;
                } elseif ($stock['can_sell'] == 0) {
                    //关盘
                    $result["msg"] = "该股票已经满仓,不能卖出！!";
                    return $result;
                }

                //获取股票详情
                $stock_info = get_stock(array($code));
                $price = round($stock_info[$code][3], 2);
                if ($price <= 0) {
                    //停盘-禁止卖出；
                    $sql = "update stock_code set stop_pai = 1, stop_date = " . strtotime($stock_info[$code][30] . " " . $stock_info[$code][31]) . " where  code = '{$stock_code}' and type = '{$stock_type}'";
                    $db->query($sql);

                    //提示禁止卖出
                    $result["msg"] = "卖出股票失败，该股票已停牌！";
                    return $result;
                } else {
                    if ($stock['stop_pai'] == 1) {
                        //开牌
                        $sql = "update stock_code set stop_pai = 0, stop_date = 0 where  code = '{$stock_code}' and type = '{$stock_type}'";
                        $db->query($sql);
                    }
                }

                //股票管理 - 涨跌幅-算法3：round((当前价 - 昨日收盘价) * 100 / 昨日收盘价, 2); round(($v[3]-$v[2]) * 100 / $v[2], 2);
                $zdf = round(round($price - $stock_info[$code][2], 2) * 100 / $stock_info[$code][2], 2);
                if(($bull_type == 2 && $zdf >= 9.98) || ($bull_type == 1 && $zdf <= -9.98)) {
                    //买涨小于-9.98，买跌大于9.98
                    $result["msg"] = "涨跌幅 " . $zdf . "%，超出9.98%个点,暂停交易！";
                    return $result;
                }

                //判断是委托卖出还是市价卖出
                if ($sell_price > 0) {
                    //查询委托表大于指定数量不允许买入
                    $sql = "select count(*) as c from stock_trust where uid = {$uid} and status = 0 and trust_type = 2";
                    $res = $db->query($sql)->row_array();
                    $trust_num = $res["c"];

                    //委托数量不能超出最大限制
                    if ($trust_num > $config_sys["trust_num"]) {
                        //提示禁止卖出
                        $result["msg"] = "委托数量超出限制范围，必须小于数量：" . $config_sys["trust_num"];
                        return $result;
                    }

                    //判断委托价格是否等于当前价格
                    if ($sell_price != $price) {
                        if ($bull_type == 1) {
                            //买升
                            if ($sell_price < $price) {
                                //提示禁止买入
                                $result["msg"] = "委托价超出限制范围，必须大于当前价格：{$price}";
                                return $result;
                            }

                            //涨幅
                            $zf = ($sell_price - $price) / $price * 100;
                            if ($zf > 2) {
                                $sell_price = round($price * (1 + 0.02), 2);
                                $result["msg"] = "委托价超出范围，最高价为：{$sell_price}";
                                return $result;
                            }
                        } else {
                            //买跌
                            if ($sell_price > $price) {
                                //提示禁止买入
                                $result["msg"] = "委托价超出限制范围，必须小于当前价格：{$price}";
                                return $result;
                            }

                            //跌幅
                            $zf = ($price - $sell_price) / $price * 100;
                            if ($zf > 2) {
                                $sell_price = round($price * (1 - 0.02), 2);
                                $result["msg"] = "委托价超出范围，最低价为：{$sell_price}";
                                return $result;
                            }
                        }

                        //开启事务
                        $db->trans_begin();

                        //插入委托表
                        $money = round($sell_price * $num, 2);
                        $sql = "insert into `stock_trust` (aid, uid, username, bull_id, stock_type, stock_code, stock_name, price, bull_type, num, money, trust_type, stock_trust_time, stock_deal_time, status) values ({$aid}, {$uid}, '{$username}', {$bull_id}, '{$stock_type}', '{$stock_code}', '{$stock_name}', {$sell_price}, {$bull_type}, {$num}, {$money}, {$trust_type}, {$stock_trust_time}, {$stock_deal_time}, {$status})";
                        $db->query($sql);
                        if (! $db->insert_id()) {
                            //事务回滚
                            $db->trans_rollback();

                            //返回结果
                            $result["msg"] = "委托失败（100）";
                            return $result;
                        }

                        //更新持仓数量
                        $sql = "update stock_bull set can_sell_num = can_sell_num - {$num} where id = {$id}";
                        $db->query($sql);
                        if (! $db->affected_rows()) {
                            //事务回滚
                            $db->trans_rollback();

                            //返回结果
                            $result["msg"] = "委托失败（101）";
                            return $result;
                        }

                        //提交事务
                        $db->trans_commit();

                        $result["status"] = 1;
                        $result["msg"] = "已委托";
                        return $result;
                    }
                } else {
                    $sell_price = $price;
                }
            } else {
                //获取股票详情
                $stock_info = get_stock(array($code));
                $sell_price = round($stock_info[$code][3], 2);
                if ($sell_price <= 0) $sell_price = round($stock_info[$code][2], 2);
                if ($num <= 0) $num = $row["can_sell_num"];
            }
            $limit_time=$config_sys['sell_limit_interval'];
            $last_time=time()-$limit_time;
            $last_sql="select  * from stock_sell where sell_time >={$last_time} and aid={$uid} and uid={$uid}  order by sell_time desc limit 1";

            $last_list=$db->query($last_sql)->result_array();
            if($last_list){
                //返回结果
                $result["msg"] = "操作频繁，请稍后再试！";
                return $result;
            }
            //开启事务
            $db->trans_begin();

            //卖出股票
            $data["price"] = $sell_price;//卖出价格
            $data["num"] = $num;//卖出数量
            $data["bull_type"] = $bull_type;//股票类型1-融资，2-融券
            $data["bull_price"] = $bull_price;//买入价格
            $data["stock_code"] = $stock_code;//股票代码
            $data["bull_time"] = $bull_time;//建仓时间

            //计算卖出
            $sell = common_sell($data);

            //更新持仓（要考虑存在委托的部分）
            if ($row["bull_num"] - $row["sell_num"] - $num == 0) {
                $sql = "update `stock_bull` set can_sell_num = can_sell_num - {$num}, sell_num = sell_num + {$num}, can_sell = 0 where id = {$bull_id} and can_sell = 1";
            } else {
                $sql = "update `stock_bull` set can_sell_num = can_sell_num - {$num}, sell_num = sell_num + {$num} where id = {$bull_id} and can_sell = 1";
            }
            $db->query($sql);
            if (! $db->affected_rows()) {
                //事务回滚
                $db->trans_rollback();

                //返回结果
                $result["msg"] = "卖出失败（101）";
                return $result;
            }

            //卖出记录
            $order_no = date("YmdHis") . rand_code(5);
            $sql = "insert into `stock_sell` (aid, uid, username, stock_code, stock_type, stock_name, sell_type, sell_price, sell_money, gain, sell_cost, cost_money, save_day, save_cost, save_money, stamp_cost, stamp_money, manage_cost, manage_money, sell_trust_id, sell_trust_time, bull_id, bull_price, bull_time, sell_time, sell_num, order_no) values ({$aid}, {$uid}, '{$username}', '{$stock_code}', '{$stock_type}', '{$stock_name}', {$bull_type}, {$sell_price}, {$sell["sell_money"]}, {$sell["gain"]}, {$sell["sell_cost"]}, {$sell["cost_money"]}, {$sell["save_day"]}, {$sell["save_cost"]}, {$sell["save_money"]}, {$sell["stamp_cost"]}, {$sell["stamp_money"]}, {$sell["manage_cost"]}, {$sell["manage_money"]}, 0, 0, {$bull_id}, {$bull_price}, {$bull_time}, {$now}, {$num}, {$order_no})";
            $db->query($sql);
            if (! $db->insert_id()) {
                //事务回滚
                $db->trans_rollback();

                //返回结果
                $result["msg"] = "卖出失败（102）";
                return $result;
            }

            //更新账户
            $remark = "市价卖出股票(平仓单号:{$order_no},数量:{$data["num"]},单价:{$sell_price},金额:{$sell["sell_money"]},股票名称:{$stock_name},印花税:{$sell["stamp_money"]},管理费:{$sell["manage_money"]},留仓费:{$sell["save_money"]},卖出手续费:{$sell["cost_money"]});";
            $res = common_user($uid, $sell["total_gain"], $sell["amount"], $sell["total_gain"], $remark);
            if (! $res) {
                //事务回滚
                $db->trans_rollback();

                //返回结果
                $result["msg"] = "卖出失败（100）";
                return $result;
            }

            //提交事务
            $db->trans_commit();

            //操作成功
            $result["status"] = 1;
            $result["msg"] = "股票已卖出！";
            return $result;
        } else {
            $result["status"] = 0;
            $result["msg"] = "持仓单处理中，请刷新页面重试";
            return $result;
        }
    }

    //返回结果
    return $result;
}

/**
 * auto_bull_trust 					委托；（自动买入股票）-PHP自动运行执行；功能独立
 * @return 	boolean	$result			状态：大于0-失败，0-成功
 */
function auto_trust() {
    //返回结果
    $result["status"] = 0;

    //获取休市状态
    $holiday = get_holiday();

    //判断是否可以进行交易
    if ($holiday == true) {
        //全部参数
        global $db;
        global $config_sys;
        $open_am_start = $config_sys["open_am_start"];//上午开市时间
        $open_am_end = $config_sys["open_am_end"];//上午关市时间
        $open_pm_start = $config_sys["open_pm_start"];//下午开市时间
        $open_pm_end = $config_sys["open_pm_end"];//下午关市时间
        $bull_cost = $config_sys["bull_cost"];//买入手续费率
        $now = date("H:i");//交易时间
        $time = time();
        $start = strtotime(date("Y-m-d"));

        //收市时间未达到委托金额，强制撤单，恢复额度,第一天未执行，第二天开市之前执行
        if ($now < $open_am_start || ($now > $open_am_end && $now < $open_pm_start) || $now > date("14:57")) {
            //开启事务
            $db->trans_begin();

            //全部撤销
            $trust = common_trust("all");
            if ($trust["status"] == 0) {
                //事务回滚
                $db->trans_rollback();

                //返回结果
                $result["msg"] = "自动撤销挂单失败！";
                return $result;
            }

            //事务提交
            $db->trans_commit();
        } else {
            //开启事务
            $db->trans_begin();

            //查询所有委托单（只查今天的委托单）
            $sql = "select *, concat(stock_type, stock_code) as code from `stock_trust` where status = 0";
            $list = $db->query($sql)->result_array();

            //格式化股票信息
            $stock_code = array_column($list, "code");
            $stock_info = get_stock($stock_code);

            //股票管理：停牌，禁卖，
            $code = array_column($list, "stock_code");
            $code = implode(",", $code);
            $sql = "select open, concat(type, code) as code, stop_pai, can_sell FROM `stock_code` where code in ({$code}) and (can_sell = 0 or open = 0)";
            $stock = $db->query($sql)->result_array();
            if ($stock) $stock = array_column($stock, null, "code");

            //遍历数据
            $up_sql = $b_in_sql = $s_in_sql = "";
            foreach ($list as $key => $val) {
                //购买类型(1=多/涨/融资 2=空/跌/融券)
                $bull_type = $val["bull_type"];
                $price = round($stock_info[$val["code"]][3], 2);//当前价格

                //判断委托类型
                if ($val["trust_type"] == 1) {
                    //委托买入
                    $buy_price = $val["price"];//委托价格

                    //判断委托单是否满足交易:买涨-当前价格小于委托价格，买跌-当前价格大于委托价格（当前价格要大于0，防止停盘交易）
                    if($price > 0 && (($bull_type == 1 &&  $price <= $buy_price) || ($bull_type == 2 && $price >= $buy_price))) {
                        //买入手续费
                        $bull_cost_money = round($val["money"] * $bull_cost, 2);
                        $amount = $val["money"] + ($bull_cost_money * 10);//最新额度 = 股票金额 + （ 买入手续费 * 10）

                        //买入记录
                        $order_no = date("YmdHis") . rand_code(5);
                        $b_in_sql .= "({$val["aid"]}, {$val["uid"]}, '{$val["username"]}', '{$val["stock_code"]}', '{$val["stock_type"]}', '{$val["stock_name"]}', {$bull_type}, {$buy_price}, {$val["num"]}, {$val["money"]}, $bull_cost, $bull_cost_money, {$val["id"]}, {$val["stock_trust_time"]}, {$time}, {$val["num"]}, $order_no),";

                        //更新状态
                        $up_sql .= ", " . $val["id"];
                    }
                } else {
                    //委托卖出
                    $sell_price = $val["price"];//委托价格

                    //判断股票最新状态
                    if($stock && ($stock[$val["code"]]['can_sell'] == 0 || $stock[$val["code"]]['open'] == 0)) {
                        //关盘
                        continue;
                    }

                    //判断股票是否允许交易
                    if ($price <= 0) {
                        //停盘-禁止卖出；
                        $stop_date = strtotime($stock_info[$val["code"]][30] . " " . $stock_info[$val["code"]][31]);
                        $sql = "update stock_code set stop_pai = 1, stop_date = {$stop_date} where  code = '{$val["stock_code"]}' and type = '{$val["stock_type"]}'";
                        $db->query($sql);
                        continue;
                    } else {
                        if($stock && $stock[$val["code"]]['stop_pai'] == 1) {
                            //开牌
                            $sql = "update stock_code set stop_pai = 0, stop_date = 0 where  code = '{$val["stock_code"]}' and type = '{$val["stock_type"]}'";
                            $db->query($sql);
                        }
                    }

                    //判断委卖市价是否达委卖价格：卖涨-当前价格大于委托价格，卖跌-当前价格小于委托价格（当前价格要大于0，防止停盘交易）
                    if ($price > 0 && (($bull_type == 1 && $price >= $sell_price) || ($bull_type == 2 && $price <= $sell_price))) {
                        //查询持仓
                        $sql = "select bull_price, bull_time, bull_num, can_sell_num, sell_num, stock_code from `stock_bull` where id = " . $val["bull_id"] . " and can_sell = 1";
                        $row = $db->query($sql)->row_array();

                        //设置参数
                        $data["price"] = $sell_price;//卖出价格
                        $data["num"] = $val["num"];//卖出数量
                        $data["bull_type"] = $bull_type;//股票类型1-融资，2-融券
                        $data["bull_price"] = $row["bull_price"];//买入价格
                        $data["stock_code"] = $row["stock_code"];//股票代码
                        $data["bull_time"] = $row["bull_time"];//建仓时间

                        //计算卖出
                        $sell = common_sell($data);

                        //更新持仓（要考虑存在委托的部分）
                        if ($row["bull_num"] - $row["sell_num"] - $val["num"] <= 0) {
                            $sql = "update `stock_bull` set sell_num = sell_num + {$val["num"]}, can_sell = 0 where id = " . $val["bull_id"] . " and can_sell = 1";
                        } else {
                            $sql = "update `stock_bull` set sell_num = sell_num + {$val["num"]} where id = " . $val["bull_id"]. " and can_sell = 1";;
                        }
                        $db->query($sql);
                        if (! $db->affected_rows()) {
                            //事务回滚
                            $db->trans_rollback();

                            //返回结果
                            $result["msg"] = "自动挂单失败！（101）";
                            return $result;
                        }

                        //卖出记录
                        $order_no = date("YmdHis") . rand_code(5);
                        $s_in_sql .= "({$val["aid"]}, {$val["uid"]}, '{$val["username"]}', '{$val["stock_code"]}', '{$val["stock_type"]}', '{$val["stock_name"]}', {$bull_type}, {$sell_price}, {$sell["sell_money"]}, {$sell["gain"]}, {$sell["sell_cost"]}, {$sell["cost_money"]}, {$sell["save_day"]}, {$sell["save_cost"]}, {$sell["save_money"]}, {$sell["stamp_cost"]}, {$sell["stamp_money"]}, {$sell["manage_cost"]}, {$sell["manage_money"]}, {$val["id"]}, {$time}, {$val["bull_id"]}, {$row["bull_price"]}, {$row["bull_time"]}, {$time}, {$val["num"]}, {$order_no}),";

                        //更新账户
                        $remark = "限价卖出股票(平仓单号:{$order_no},数量:{$data["num"]},单价:{$data["price"]},金额:{$sell["sell_money"]},股票名称:{$val["stock_name"]},印花税:{$sell["stamp_money"]},管理费:{$sell["manage_money"]},留仓费:{$sell["save_money"]},卖出手续费:{$sell["cost_money"]});";
                        $res = common_user($val["uid"], $sell["total_gain"], $sell["amount"], $sell["total_gain"], $remark);
                        if (! $res) {
                            //事务回滚
                            $db->trans_rollback();

                            //返回结果
                            $result["msg"] = "自动挂单失败！（100）";
                            return $result;
                        }

                        //更新状态
                        $up_sql .= ", " . $val["id"];
                    }
                }
            }

            //自动买入
            if ($b_in_sql) {
                $b_in_sql = trim($b_in_sql, ",");
                $sql = "insert into `stock_bull` (aid, uid, username, stock_code, stock_type, stock_name, bull_type, bull_price, bull_num, bull_money, bull_cost, bull_cost_money, bull_trust_id, bull_trust_time, bull_time, can_sell_num, order_no) values " . $b_in_sql;
                $db->query($sql);
                if (! $db->insert_id()) {
                    //事务回滚
                    $db->trans_rollback();

                    //返回结果
                    $result["msg"] = "自动挂单失败！（102）";
                    return $result;
                }
            }

            //自动卖出
            if ($s_in_sql) {
                $s_in_sql = trim($s_in_sql, ",");
                $sql = "insert into `stock_sell` (aid, uid, username, stock_code, stock_type, stock_name, sell_type, sell_price, sell_money, gain, sell_cost, cost_money, save_day, save_cost, save_money, stamp_cost, stamp_money, manage_cost, manage_money, sell_trust_id, sell_trust_time, bull_id, bull_price, bull_time, sell_time, sell_num, order_no) values " . $s_in_sql;
                $db->query($sql);
                if (! $db->insert_id()) {
                    //事务回滚
                    $db->trans_rollback();

                    //返回结果
                    $result["msg"] = "自动挂单失败！（103）";
                    return $result;
                }
            }

            //更新状态
            if ($up_sql) {
                $up_sql = trim($up_sql, ",");
                $sql = "update `stock_trust` set status = 1, stock_deal_time = {$time} where status = 0 and id in ($up_sql)";
                $db->query($sql);
                if (! $db->affected_rows()) {
                    //事务回滚
                    $db->trans_rollback();

                    //返回结果
                    $result["msg"] = "自动挂单失败！（104）";
                    return $result;
                }
            }

            //提交事务
            $db->trans_commit();
        }
    }

    //返回结果
    $result["status"] = 1;
    $result["msg"] = "自动挂单成功";
    return $result;
}

/**
 * auto_drxd 						除权除息；（自动卖出所有股票）-PHP自动运行执行；功能独立
 * @return 	boolean	$result			状态：大于0-失败，0-成功
 */
function auto_drxd() {
    //返回结果
    $result["status"] = 0;

    //全局参数
    global $db;

    //下午结算除权除息股票
    if (DEVELOPMENT_ENVIRONMENT == false && date("H:i") < date("14:57")) {
        $result["msg"] = "开市期间，不可强制执行！";
        return $result;
    }

    //查询关盘股票
    $sql = "SELECT code FROM `stock_code` where open = 0";
    $stock = $db->query($sql)->result_array();
    if ($stock) {
        //开启事务
        $db->trans_begin();

        //格式化股票代码
        $stock = array_column($stock, "code");
        $code = implode(",", $stock);

        //查询所有委托单（不能分批次处理，防止出现重复撤销单）
        $sql = "select id from `stock_trust` where status = 0 and stock_code in ({$code})";
        $res = $db->query($sql)->result_array();
        if ($res) {
            //全部撤销
            $trust_id = implode(",", array_column($res, "id"));
            $trust = common_trust($trust_id);
            if ($trust["status"] == 0) {
                //事务回滚
                $db->trans_rollback();

                //返回结果
                $result["msg"] = "除权除息撤单失败！";
                return $result;
            }
        }

        //卖出所有持仓单：执行强制卖出（分批次处理，每次执行50条，防止系统卡死。）
        $sql = "select id bull_id, aid, uid, username, stock_type, stock_code, stock_name, can_sell_num, bull_type, bull_price, bull_time, concat(stock_type, stock_code) as code from `stock_bull` where can_sell = 1 and stock_code in ({$code}) limit 50";
        $list = $db->query($sql)->result_array();

        //存在持仓单
        $auto = common_auto($list);
        if ($auto["status"] == 0) {
            //事务回滚
            $db->trans_rollback();

            //结果集
            $result["msg"] = "除权除息卖出失败（100）";
            return $result;
        }

        //提交事务
        $db->trans_commit();
    }

    //返回结果
    $result["status"] = 1;
    $result["msg"] = "除权除息卖出成功";
    return $result;
}
/**
 * [自动计算留仓费]
 * @return [type] [description]
 */
function  auto_storagefee(){

}
/**
 * auto_force 						爆仓；（自动卖出所有股票）-PHP自动运行执行；功能独立（1：强制卖出10天股票，2：保证金率低于10%强制卖出所有股票）
 * @return 	boolean	$result			状态：大于0-失败，0-成功
 */
function auto_force() {
    //结果集
    $result["status"] = 0;

    //全局变量
    global $db;
    global $config_sys;

    //配置参数
    $save_day = isset($config_sys["save_day"]) ? $config_sys["save_day"] : 10;//10 - 12天，考虑到周五股票留仓8，9天
    $now = date("Y-m-d H:i");//当前时间

    $time = time();

    if (date("w") == 1) {
        //周一平仓：到周五8，9天的股票
        $start = strtotime(date("Y-m-d", strtotime("-12 day")));
        $end = strtotime(date("Y-m-d 23:59:59", strtotime("-10 day")));
        $ten_day=strtotime(date("Y-m-d", strtotime("-10 day")));
    } else {
        //其他时间正常平仓
        $start = strtotime(date("Y-m-d", strtotime("-$save_day day")));
        $end = strtotime(date("Y-m-d 23:59:59", strtotime("-$save_day day")));
        $ten_day=strtotime(date("Y-m-d", strtotime("-$save_day day")));
    }

    //开启事务
    $db->trans_begin();

    //1：强制卖出10天前股票（判断当前时间是否到达下午结算时间）
    if ($now > date("Y-m-d 14:54")) {
        //查询记录
        $sql = "select id bull_id, aid, uid, username, stock_type, stock_code, stock_name, can_sell_num, bull_type, bull_price, bull_time, concat(stock_type, stock_code) as code from `stock_bull` where can_sell = 1 and bull_time <= {$end}";
        $list = $db->query($sql)->result_array();

        //存在持仓单
        $auto = common_auto($list);
        if ($auto["status"] == 0) {
            //事务回滚
            $db->trans_rollback();

            //结果集
            $result["msg"] = "自动爆仓失败（100）";
            return $result;
        }
    }

    //2：强制卖出保证金率小于10%的股票
    $sql = "select uid from `stock_bull` where can_sell = 1 and bull_time >= {$start} GROUP BY uid";
    $res = $db->query($sql)->result_array();
    $uid = array_column($res, "uid");
    $uid = implode(",", $uid);
    $user = get_user($uid, 1);

    //循环检查用户保证金率
    $temp_uid = array();
    $m_sql_1 = "";
    if ($user) {
        foreach ($user as $val) {
            //判断用户保证金率是否小于10%
            if ($val["ratio"] <= 10) {
                //统计强制爆仓用户
                array_push($temp_uid, $val["id"]);
            }
        }
    }

    //判断是否存在爆仓
    if ($temp_uid) {
        $temp_uid = implode(",", $temp_uid);

        //查询所有委托单
        $sql = "select id from `stock_trust` where status = 0 and uid in ({$temp_uid})";
        $res = $db->query($sql)->result_array();
        if ($res) {
            //全部撤销
            $trust_id = implode(",", array_column($res, "id"));
            $trust = common_trust($trust_id);
            if ($trust["status"] == 0) {
                //事务回滚
                $db->trans_rollback();

                //结果集
                $result["msg"] = "自动爆仓失败（102）";
                return $result;
            }
        }

        //查询记录（分批次处理，每次执行50条，防止系统卡死。）
        $sql = "select id bull_id, aid, uid, username, stock_type, stock_code, stock_name, can_sell_num, bull_type, bull_price, bull_time, concat(stock_type, stock_code) as code from `stock_bull` where can_sell = 1 and uid in ({$temp_uid}) limit 50";
        $list = $db->query($sql)->result_array();

        //存在持仓单
        $auto = common_auto($list);
        if ($auto["status"] == 0) {
            //事务回滚
            $db->trans_rollback();

            //结果集
            $result["msg"] = "自动爆仓失败（103）";
            return $result;
        }

        //爆仓短信
        $bc_uid = array_column($list, "uid");
        $bc_uid = array_unique($bc_uid);
        foreach ($bc_uid as $v) {
            if (isset($user[$v])) {
                $val = $user[$v];
                $title = "用户【{$val["username"]}】在{$now}股票被爆仓.";
                $content = "用户名：{$val["username"]}<br />代理商：{$val["agent_name"]}<br />总亏损：{$val["total_gain"]}<br />保证金率：{$val["ratio"]}%<br />爆仓时间：{$now}";
                $m_sql_1 .= ", ({$val["aid"]}, '0', '{$val["id"]}', '{$title}', '{$content}', '0')";
            }
        }
    }

    //发送爆仓站内信
    if ($m_sql_1) {
        $m_sql_1 = trim($m_sql_1, ",");
        $sql = "insert into message (aid, sender, receiver, title, content, isread) values " . $m_sql_1;
        $db->query($sql);
        if (! $db->insert_id()) {
            //事务回滚
            $db->trans_rollback();

            //返回结果
            $result["msg"] = "自动爆仓失败（101）";
            return $result;
        }
    }

    //提交事务
    $db->trans_commit();

    //返回结果
    $result["status"] = 1;
    $result["msg"] = "自动爆仓成功";
    return $result;
}

/**
 * common_auto 						自动程序通用函数
 * @return 	array	$result			结果集
 */
function common_auto($list = array()) {
    if ($list) {
        $result["status"] = 0;

        //全局参数
        global $db;

        //股票行情
        $stock_info = array_column($list, "code");
        $stock_info = get_stock($stock_info);
        $time = time();

        //循环卖出
        $s_in_sql = "";
        foreach ($list as $key => $val) {
            //股票最新价格，如果停盘交易价格按照昨天收盘价格收盘
            $sell_price = round(@$stock_info[$val["code"]][3], 2);
            if ($sell_price <= 0) $sell_price = round(@$stock_info[$val["code"]][2], 2);

            //设置参数
            $data["price"] = $sell_price;//卖出价格
            $data["num"] = $val["can_sell_num"];//卖出数量
            $data["bull_type"] = $val["bull_type"];//股票类型1-融资，2-融券
            $data["bull_price"] = $val["bull_price"];//买入价格
            $data["stock_code"] = $val["stock_code"];//股票代码
            $data["bull_time"] = $val["bull_time"];//建仓时间

            //计算卖出
            $sell = common_sell($data);

            //更新持仓
            $sql = "update `stock_bull` set can_sell_num = 0, sell_num = sell_num + {$val["can_sell_num"]}, can_sell = 0 where can_sell = 1 and id = {$val["bull_id"]}";
            $db->query($sql);
            if (! $db->affected_rows()) {
                //返回结果
                $result["msg"] = "更新持仓失败（101）";
                return $result;
            }

            //卖出记录
            $order_no = date("YmdHis") . rand_code(5);
            $s_in_sql .= "({$val["aid"]}, {$val["uid"]}, '{$val["username"]}', '{$val["stock_code"]}', '{$val["stock_type"]}', '{$val["stock_name"]}', {$val["bull_type"]}, {$sell_price}, {$sell["sell_money"]}, {$sell["gain"]}, {$sell["sell_cost"]}, {$sell["cost_money"]}, {$sell["save_day"]}, {$sell["save_cost"]}, {$sell["save_money"]}, {$sell["stamp_cost"]}, {$sell["stamp_money"]}, {$sell["manage_cost"]}, {$sell["manage_money"]}, 0, 0, {$val["bull_id"]}, {$val["bull_price"]}, {$val["bull_time"]}, {$time}, {$val["can_sell_num"]}, {$order_no}),";

            //更新账户
            $remark = "强制卖出股票(平仓单号:{$order_no},数量:{$data["num"]},单价:{$data["price"]},金额:{$sell["sell_money"]},股票名称:{$val["stock_name"]},印花税:{$sell["stamp_money"]},管理费:{$sell["manage_money"]},留仓费:{$sell["save_money"]},卖出手续费:{$sell["cost_money"]});";
            $res = common_user($val["uid"], $sell["total_gain"], $sell["amount"], $sell["total_gain"], $remark);
            if (! $res) {
                //事务回滚
                $db->trans_rollback();

                //返回结果
                $result["msg"] = "自动爆仓失败！（100）";
                return $result;
            }
        }

        //自动卖出
        if ($s_in_sql) {
            $s_in_sql = trim($s_in_sql, ",");
            $sql = "insert into `stock_sell` (aid, uid, username, stock_code, stock_type, stock_name, sell_type, sell_price, sell_money, gain, sell_cost, cost_money, save_day, save_cost, save_money, stamp_cost, stamp_money, manage_cost, manage_money, sell_trust_id, sell_trust_time, bull_id, bull_price, bull_time, sell_time, sell_num, order_no) values " . $s_in_sql;
            $db->query($sql);
            if (! $db->insert_id()) {
                //返回结果
                $result["msg"] = "执行卖出失败（101）";
                return $result;
            }
        }
    }

    //返回结果
    $result["status"] = 1;
    $result["msg"] = "成功卖出";
    return $result;
}

/**
 * common_sell 						卖出股票通用函数
 * @return 	array	$result			结果集
 */
function common_sell($data = array()) {
    if (is_array($data)) {
        //初始化配置
        global $config_sys;

        //设置参数
        $price = $data["price"];//卖出价格
        $num = $data["num"];//卖出数量
        $bull_type = $data["bull_type"];//股票类型1-融资，2-融券
        $bull_price = $data["bull_price"];//买入价格
        $stock_code = $data["stock_code"];//股票代码
        $bull_time = $data["bull_time"];//建仓时间

        $bull_cost = $config_sys["bull_cost"];//买入手续费率
        $sell_cost = $config_sys["sell_cost"];//卖出手续费率
        $save_cost = $config_sys["save_cost"];//留仓费率(利息)
        $stamp_cost = $config_sys["stamp"];//印花税率
        $manage_cost = $config_sys["manage_cost"];//管理费率(利息)
        $rest_filter = $config_sys["rest_filter"];//周六，周日免收手续费

        //买入手续费
        $bull_cost_money = round($bull_price * $num * $bull_cost, 2);

        //卖出后收益/盈亏金额
        if ($bull_type == 1) {
            $gain = round(($price - $bull_price) * $num, 2);//卖出后收益/盈亏金额
        } else {
            $gain = round(($bull_price - $price) * $num, 2);//卖出后收益/盈亏金额
        }

        //卖出总金额
        $sell_money = round($price * $num, 2);

        //卖出后费用
        $cost_money = round($sell_money * $sell_cost, 2);//卖出手续费金额
        $stamp_money = round($sell_money * $stamp_cost, 2);//印花税金额
        if (substr($stock_code, 0, 3) == "002" || substr($stock_code, 0, 3) == "300"){
            $manage_money = round($manage_cost * $sell_money, 2);//小股权收取管理费：002、300开头股票
        } else {
            $manage_money = 0;
        }

        //计算留仓天数
        $now_date = strtotime(date("Y-m-d"));
        $sta_date = strtotime(date("Y-m-d", $bull_time));
        $save_day = round(($now_date - $sta_date) / 86400);

        //全局变量
        global $db;
        //节假日是否收取手续费：0-不计算，1-计算
        // $sql="select * from config_holiday where begin_date>={$sta_date} and end_date < {$now_date}";
        $sql="select * from config_holiday where is_storagefee=0";
        $holiday_list = $db->query($sql)->result_array();
        if(!empty($holiday_list)){
            foreach ($holiday_list as $key => $value) {
                if($value["end_date"]>=$sta_date){
                    if(strtotime(date('Y-m-d'))>$value["end_date"]){
                        $timespan=($value["end_date"]-$value["begin_date"])/(3600*24)+1;
                        if($timespan > 0){
                            $save_day-=$timespan;
                        }
                    }else{
                        $timespan=(strtotime(date('Y-m-d'))-$value["begin_date"])/(3600*24);
                        if($timespan > 0){
                            $save_day-=$timespan;
                        }
                    }
                }
            }
        }else{
            //判断星期六，星期日，0-不计算，1-计算
            if ($rest_filter == 0) {
                for ($i = 1; $i < $save_day; $i ++) {
                    $w = date('w');
                    //判断星期六，星期日
                    if ($w == 0 || $w == 6) {
                        $save_day --;
                    }
                }
            }
        }

        //留仓费金额（利息）
        $save_money = round($sell_money * $save_cost * $save_day, 2);

        //卖出总手续费
        $fee = round($cost_money + $save_money + $stamp_money + $manage_money, 2);

        //卖出总盈亏
        $total_gain = round($gain - $fee, 2);

        //可用额度
        if ($bull_type == 1) {
            //融资:卖出金额 - 盈亏 + （浮盈 * 10）
            $amount = round($sell_money - $gain + ($total_gain * 10), 2);//可用额度
        } else {
            //融券:卖出金额 + 盈亏 + （浮盈 * 10）
            $amount = round($sell_money + $gain + ($total_gain * 10), 2);//可用额度
        }

        //盈亏比例
        if ($sell_money > 0) {
            $loss = round((($total_gain - $bull_cost_money) / $sell_money) * 100, 2);
        } else {
            $loss = 0;
        }

        //设置结果
        $result["amount"] = $amount;//可用额度
        $result["sell_money"] = $sell_money;//卖出金额
        $result["total_gain"] = $total_gain;//卖出总盈亏
        $result["gain"] = $gain;//卖出总盈亏
        $result["fee"] = $fee;//卖出总手续费
        $result["sell_cost"] = $sell_cost;//卖出费率
        $result["cost_money"] = $cost_money;//卖出手续费
        $result["save_day"] = $save_day;//留仓天数
        $result["save_cost"] = $save_cost;//留仓费率
        $result["save_money"] = $save_money;//留仓金额
        $result["stamp_cost"] = $stamp_cost;//印花税费率
        $result["stamp_money"] = $stamp_money;//印花税金额
        $result["manage_cost"] = $manage_cost;//管理费率
        $result["manage_money"] = $manage_money;//管理费金额
        $result["loss"] = $loss;//盈亏比例

        return $result;
    } else {
        //设置结果
        $result["amount"] = 0;//可用额度
        $result["sell_money"] = 0;//卖出金额
        $result["total_gain"] = 0;//卖出总盈亏
        $result["gain"] = 0;//卖出总盈亏
        $result["fee"] = 0;//卖出总手续费
        $result["sell_cost"] = 0;//卖出费率
        $result["cost_money"] = 0;//卖出手续费
        $result["save_day"] = 0;//留仓天数
        $result["save_cost"] = 0;//留仓费率
        $result["save_money"] = 0;//留仓金额
        $result["stamp_cost"] = 0;//印花税费率
        $result["stamp_money"] = 0;//印花税金额
        $result["manage_cost"] = 0;//管理费率
        $result["manage_money"] = 0;//管理费金额
        $result["loss"] = 0;//盈亏比例

        return $result;
    }
}

/**
 * common_trust 					撤单；（撤销委托买入，卖出）
 * @param 	int 	$id				委托单ID
 * @param 	int 	$uid			用户ID
 * @return 	boolean	$result			状态：大于0-失败，0-成功
 */
function common_trust($id = 0, $trust_type = 1) {
    //全局参数
    global $db;
    global $config_sys;

    //设置参数
    $trust_type = intval($trust_type);
    if ($trust_type != 1) $trust_type = 2;

    //返回结果
    $result["status"] = 0;
    $time = time();

    //撤销类型
    if ($id == "all") {
        //全部撤销
        $sql = "select id, uid, num, money, bull_id, trust_type from `stock_trust` where status = 0";
        $list = $db->query($sql)->result_array();

        //遍历数据
        $up_sql = "";
        foreach ($list as $key => $val) {
            if ($val["trust_type"] == 2) {
                //恢复持仓数量
                $sql = "update `stock_bull` set can_sell_num = can_sell_num + {$val["num"]} where can_sell = 1 and id = {$val["bull_id"]}";
                $db->query($sql);
                if (! $db->affected_rows()) {
                    //返回结果
                    $result["msg"] = "更新持仓数量失败";
                    return $result;
                }
            } else {
                //计算结算
                $bull_cost = $config_sys["bull_cost"];//买入手续费
                $bull_cost_money = round($bull_cost * $val["money"], 2);//买入手续费金额
                $amount = round($val["money"] + ($bull_cost_money * 10), 2);//可用额度

                //恢复额度
                $res = common_user($val["uid"], $bull_cost_money, $amount, $bull_cost_money, "委托买入撤单（全部）");
                if (! $res) {
                    //返回结果
                    $result["msg"] = "恢复额度失败";
                    return $result;
                }
            }
            $up_sql .= "," . $val["id"];
        }

        //更新状态
        if ($up_sql) {
            $up_sql = trim($up_sql, ",");
            $sql = "update `stock_trust` set status = 2, block = 0, stock_deal_time = {$time} where status = 0 and id in ({$up_sql})";
            $db->query($sql);
            if (! $db->affected_rows()) {
                //返回结果
                $result["msg"] = "更新委托状态失败";
                return $result;
            }
        }
    } elseif (is_numeric($id)) {
        //撤销单条
        $sql = "select aid, uid, num, money, bull_id, trust_type from `stock_trust` where id = $id and status = 0";
        $row = $db->query($sql)->row_array();
        if ($row["trust_type"] == 2) {
            //恢复持仓数量
            $sql = "update `stock_bull` set can_sell_num = can_sell_num + {$row["num"]} where can_sell = 1 and id = {$row["bull_id"]}";
            $db->query($sql);
            if (! $db->affected_rows()) {
                //返回结果
                $result["msg"] = "更新持仓数量失败";
                return $result;
            }
        } else {
            //计算结算
            $bull_cost = $config_sys["bull_cost"];//买入手续费
            $bull_cost_money = round($bull_cost * $row["money"], 2);//买入手续费金额
            $amount = round($row["money"] + ($bull_cost_money * 10), 2);//可用额度

            //恢复额度
            $res = common_user($row["uid"], $bull_cost_money, $amount, $bull_cost_money, "委托买入撤单（单条）");
            if (! $res) {
                //返回结果
                $result["msg"] = "恢复额度失败";
                return $result;
            }
        }

        //更新状态
        $sql = "update `stock_trust` set status = 2, block = 0, stock_deal_time = {$time} where status = 0 and id = $id";
        $db->query($sql);
        if (! $db->affected_rows()) {
            //返回结果
            $result["msg"] = "更新委托状态失败";
            return $result;
        }
    } else {
        //撤销多条
        $sql = "select aid, uid, num, money, bull_id, trust_type from `stock_trust` where status = 0 and id in ($id)";
        $list = $db->query($sql)->result_array();

        //遍历数据
        $up_sql = "";
        foreach ($list as $key => $val) {
            if ($val["trust_type"] == 2) {
                //恢复持仓数量
                $sql = "update `stock_bull` set can_sell_num = can_sell_num + {$val["num"]} where can_sell = 1 and id = {$val["bull_id"]}";
                $db->query($sql);
                if (! $db->affected_rows()) {
                    //返回结果
                    $result["msg"] = "更新持仓数量失败";
                    return $result;
                }
            } else {
                //计算结算
                $bull_cost = $config_sys["bull_cost"];//买入手续费
                $bull_cost_money = round($bull_cost * $val["money"], 2);//买入手续费金额
                $amount = round($val["money"] + ($bull_cost_money * 10), 2);//可用额度

                //恢复额度
                $res = common_user($val["uid"], $bull_cost_money, $amount, $bull_cost_money, "委托买入撤单（多条）");
                if (! $res) {
                    //返回结果
                    $result["msg"] = "恢复额度失败";
                    return $result;
                }
            }
            $up_sql .= "," . $val["id"];
        }

        //更新状态
        if ($up_sql) {
            $up_sql = trim($up_sql, ",");
            $sql = "update `stock_trust` set status = 2, block = 0, stock_deal_time = {$time} where status = 0 and id in ({$up_sql})";
            $db->query($sql);
            if (! $db->affected_rows()) {
                //返回结果
                $result["msg"] = "更新委托状态失败";
                return $result;
            }
        }
    }

    //返回结果
    $result["status"] = 1;
    $result["msg"] = "撤销委托单成功";
    return $result;
}

function getParam(){
    $info = json_decode(file_get_contents('php://input'),true);
    return $info;
}

/**
 * common_user 						用户资金变动
 * @param 	int 	$finance		保证金
 * @param 	int 	$amount			额度
 * @param 	int 	$gain			盈亏
 * @return 	boolean	$result			状态：大于0-失败，0-成功
 */
function common_user($uid = 0, $finance = 0, $amount = 0, $gain = 0, $remark = "") {
    //预留功能
    $uid = intval($uid);
    if ($uid > 0) {
        //全局参数
        global $db;

        //查询账户
        $sql = "select aid, finance, amount, gain from user where id = $uid";
        $row = $db->query($sql)->row_array();
        if (!$row) return false;

        //更新账户
        $sql = "update user set finance = finance + {$finance}, amount = amount + {$amount}, gain = gain + {$gain} where id = {$uid}";
        $db->query($sql);
        if (! $db->affected_rows()) return false;

        //插入记录
        $fdate = date("Ymd");
        $sql = "insert into log_bill (uid, aid, finance, amount, gain, old_finance, old_amount, old_gain, remark, fdate) values ({$uid}, {$row['aid']}, {$finance}, {$amount}, {$gain}, {$row['finance']}, {$row['amount']}, {$row['gain']}, '{$remark}', {$fdate})";
        $db->query($sql);
        if (! $db->insert_id()) return false;

        return true;
    }
    return false;
}
